1////pf: javascript/jquery.js 2/*! jQuery v3.3.1 | (c) JS Foundation and other contributors | jquery.org/license */�
vendor: 86,842 bytes, lines 2-3
2 3!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){"use strict";var n=[],r=e.document,i=Object.getPrototypeOf,o=n.slice,a=n.concat,s=n.push,u=n.indexOf,l={},c=l.toString,f=l.hasOwnProperty,p=f.toString,d=p.call(Object),h={},g=function e(t){return"function"==typeof t&&"number"!=typeof t.nodeType},y=function e(t){return null!=t&&t===t.window},v={type:!0,src:!0,noModule:!0};function m(e,t,n){var i,o=(t=t||r).createElement("script");if(o.text=e,n)for(i in v)n[i]&&(o[i]=n[i]);t.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[c.call(e)]||"object":typeof e}var b="3.3.1",w=function(e,t){return new w.fn.init(e,t)},T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;w.fn=w.prototype={jquery:"3.3.1",constructor:w,length:0,toArray:function(){return o.call(this)},get:function(e){return null==e?o.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=w.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return w.each(this,e)},map:function(e){return this.pushStack(w.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(o.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:s,sort:n.sort,splice:n.splice},w.extend=w.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||g(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)n=a[t],a!==(r=e[t])&&(l&&r&&(w.isPlainObject(r)||(i=Array.isArray(r)))?(i?(i=!1,o=n&&Array.isArray(n)?n:[]):o=n&&w.isPlainObject(n)?n:{},a[t]=w.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},w.extend({expando:"jQuery"+("3.3.1"+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==c.call(e))&&(!(t=i(e))||"function"==typeof(n=f.call(t,"constructor")&&t.constructor)&&p.call(n)===d)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e){m(e)},each:function(e,t){var n,r=0;if(C(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},trim:function(e){return null==e?"":(e+"").replace(T,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(C(Object(e))?w.merge(n,"string"==typeof e?[e]:e):s.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:u.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r,i=[],o=0,a=e.length,s=!n;o<a;o++)(r=!t(e[o],o))!==s&&i.push(e[o]);return i},map:function(e,t,n){var r,i,o=0,s=[];if(C(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&s.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&s.push(i);return a.apply([],s)},guid:1,support:h}),"function"==typeof Symbol&&(w.fn[Symbol.iterator]=n[Symbol.iterator]),w.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function C(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!g(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e)}var E=function(e){var t,n,r,i,o,a,s,u,l,c,f,p,d,h,g,y,v,m,x,b="sizzle"+1*new Date,w=e.document,T=0,C=0,E=ae(),k=ae(),S=ae(),D=function(e,t){return e===t&&(f=!0),0},N={}.hasOwnProperty,A=[],j=A.pop,q=A.push,L=A.push,H=A.slice,O=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},P="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",R="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",I="\\["+M+"*("+R+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+R+"))|)"+M+"*\\]",W=":("+R+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+I+")*)|.*)\\)|)",$=new RegExp(M+"+","g"),B=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),F=new RegExp("^"+M+"*,"+M+"*"),_=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),z=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),X=new RegExp(W),U=new RegExp("^"+R+"$"),V={ID:new RegExp("^#("+R+")"),CLASS:new RegExp("^\\.("+R+")"),TAG:new RegExp("^("+R+"|[*])"),ATTR:new RegExp("^"+I),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+P+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},G=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Q=/^[^{]+\{\s*\[native \w/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,K=/[+~]/,Z=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ee=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},te=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ne=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},re=function(){p()},ie=me(function(e){return!0===e.disabled&&("form"in e||"label"in e)},{dir:"parentNode",next:"legend"});try{L.apply(A=H.call(w.childNodes),w.childNodes),A[w.childNodes.length].nodeType}catch(e){L={apply:A.length?function(e,t){q.apply(e,H.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function oe(e,t,r,i){var o,s,l,c,f,h,v,m=t&&t.ownerDocument,T=t?t.nodeType:9;if(r=r||[],"string"!=typeof e||!e||1!==T&&9!==T&&11!==T)return r;if(!i&&((t?t.ownerDocument||t:w)!==d&&p(t),t=t||d,g)){if(11!==T&&(f=J.exec(e)))if(o=f[1]){if(9===T){if(!(l=t.getElementById(o)))return r;if(l.id===o)return r.push(l),r}else if(m&&(l=m.getElementById(o))&&x(t,l)&&l.id===o)return r.push(l),r}else{if(f[2])return L.apply(r,t.getElementsByTagName(e)),r;if((o=f[3])&&n.getElementsByClassName&&t.getElementsByClassName)return L.apply(r,t.getElementsByClassName(o)),r}if(n.qsa&&!S[e+" "]&&(!y||!y.test(e))){if(1!==T)m=t,v=e;else if("object"!==t.nodeName.toLowerCase()){(c=t.getAttribute("id"))?c=c.replace(te,ne):t.setAttribute("id",c=b),s=(h=a(e)).length;while(s--)h[s]="#"+c+" "+ve(h[s]);v=h.join(","),m=K.test(e)&&ge(t.parentNode)||t}if(v)try{return L.apply(r,m.querySelectorAll(v)),r}catch(e){}finally{c===b&&t.removeAttribute("id")}}}return u(e.replace(B,"$1"),t,r,i)}function ae(){var e=[];function t(n,i){return e.push(n+" ")>r.cacheLength&&delete t[e.shift()],t[n+" "]=i}return t}function se(e){return e[b]=!0,e}function ue(e){var t=d.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function le(e,t){var n=e.split("|"),i=n.length;while(i--)r.attrHandle[n[i]]=t}function ce(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function fe(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function pe(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function de(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ie(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function he(e){return se(function(t){return t=+t,se(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function ge(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}n=oe.support={},o=oe.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},p=oe.setDocument=function(e){var t,i,a=e?e.ownerDocument||e:w;return a!==d&&9===a.nodeType&&a.documentElement?(d=a,h=d.documentElement,g=!o(d),w!==d&&(i=d.defaultView)&&i.top!==i&&(i.addEventListener?i.addEventListener("unload",re,!1):i.attachEvent&&i.attachEvent("onunload",re)),n.attributes=ue(function(e){return e.className="i",!e.getAttribute("className")}),n.getElementsByTagName=ue(function(e){return e.appendChild(d.createComment("")),!e.getElementsByTagName("*").length}),n.getElementsByClassName=Q.test(d.getElementsByClassName),n.getById=ue(function(e){return h.appendChild(e).id=b,!d.getElementsByName||!d.getElementsByName(b).length}),n.getById?(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){return e.getAttribute("id")===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n=t.getElementById(e);return n?[n]:[]}}):(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){var n="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),r.find.TAG=n.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):n.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},r.find.CLASS=n.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&g)return t.getElementsByClassName(e)},v=[],y=[],(n.qsa=Q.test(d.querySelectorAll))&&(ue(function(e){h.appendChild(e).innerHTML="<a id='"+b+"'></a><select id='"+b+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+P+")"),e.querySelectorAll("[id~="+b+"-]").length||y.push("~="),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+b+"+*").length||y.push(".#.+[+~]")}),ue(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=d.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),h.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(n.matchesSelector=Q.test(m=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ue(function(e){n.disconnectedMatch=m.call(e,"*"),m.call(e,"[s!='']:x"),v.push("!=",W)}),y=y.length&&new RegExp(y.join("|")),v=v.length&&new RegExp(v.join("|")),t=Q.test(h.compareDocumentPosition),x=t||Q.test(h.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return f=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(1&(r=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!n.sortDetached&&t.compareDocumentPosition(e)===r?e===d||e.ownerDocument===w&&x(w,e)?-1:t===d||t.ownerDocument===w&&x(w,t)?1:c?O(c,e)-O(c,t):0:4&r?-1:1)}:function(e,t){if(e===t)return f=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===d?-1:t===d?1:i?-1:o?1:c?O(c,e)-O(c,t):0;if(i===o)return ce(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?ce(a[r],s[r]):a[r]===w?-1:s[r]===w?1:0},d):d},oe.matches=function(e,t){return oe(e,null,null,t)},oe.matchesSelector=function(e,t){if((e.ownerDocument||e)!==d&&p(e),t=t.replace(z,"='$1']"),n.matchesSelector&&g&&!S[t+" "]&&(!v||!v.test(t))&&(!y||!y.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return oe(t,d,null,[e]).length>0},oe.contains=function(e,t){return(e.ownerDocument||e)!==d&&p(e),x(e,t)},oe.attr=function(e,t){(e.ownerDocument||e)!==d&&p(e);var i=r.attrHandle[t.toLowerCase()],o=i&&N.call(r.attrHandle,t.toLowerCase())?i(e,t,!g):void 0;return void 0!==o?o:n.attributes||!g?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null},oe.escape=function(e){return(e+"").replace(te,ne)},oe.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},oe.uniqueSort=function(e){var t,r=[],i=0,o=0;if(f=!n.detectDuplicates,c=!n.sortStable&&e.slice(0),e.sort(D),f){while(t=e[o++])t===e[o]&&(i=r.push(o));while(i--)e.splice(r[i],1)}return c=null,e},i=oe.getText=function(e){var t,n="",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=i(e)}else if(3===o||4===o)return e.nodeValue}else while(t=e[r++])n+=i(t);return n},(r=oe.selectors={cacheLength:50,createPseudo:se,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(Z,ee),e[3]=(e[3]||e[4]||e[5]||"").replace(Z,ee),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||oe.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&oe.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return V.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=a(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(Z,ee).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=E[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&E(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=oe.attr(r,e);return null==i?"!="===t:!t||(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i.replace($," ")+" ").indexOf(n)>-1:"|="===t&&(i===n||i.slice(0,n.length+1)===n+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,d,h,g=o!==a?"nextSibling":"previousSibling",y=t.parentNode,v=s&&t.nodeName.toLowerCase(),m=!u&&!s,x=!1;if(y){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===v:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?y.firstChild:y.lastChild],a&&m){x=(d=(l=(c=(f=(p=y)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1])&&l[2],p=d&&y.childNodes[d];while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if(1===p.nodeType&&++x&&p===t){c[e]=[T,d,x];break}}else if(m&&(x=d=(l=(c=(f=(p=t)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1]),!1===x)while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===v:1===p.nodeType)&&++x&&(m&&((c=(f=p[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]=[T,x]),p===t))break;return(x-=i)===r||x%r==0&&x/r>=0}}},PSEUDO:function(e,t){var n,i=r.pseudos[e]||r.setFilters[e.toLowerCase()]||oe.error("unsupported pseudo: "+e);return i[b]?i(t):i.length>1?(n=[e,e,"",t],r.setFilters.hasOwnProperty(e.toLowerCase())?se(function(e,n){var r,o=i(e,t),a=o.length;while(a--)e[r=O(e,o[a])]=!(n[r]=o[a])}):function(e){return i(e,0,n)}):i}},pseudos:{not:se(function(e){var t=[],n=[],r=s(e.replace(B,"$1"));return r[b]?se(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),t[0]=null,!n.pop()}}),has:se(function(e){return function(t){return oe(e,t).length>0}}),contains:se(function(e){return e=e.replace(Z,ee),function(t){return(t.textContent||t.innerText||i(t)).indexOf(e)>-1}}),lang:se(function(e){return U.test(e||"")||oe.error("unsupported lang: "+e),e=e.replace(Z,ee).toLowerCase(),function(t){var n;do{if(n=g?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===h},focus:function(e){return e===d.activeElement&&(!d.hasFocus||d.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:de(!1),disabled:de(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!r.pseudos.empty(e)},header:function(e){return Y.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:he(function(){return[0]}),last:he(function(e,t){return[t-1]}),eq:he(function(e,t,n){return[n<0?n+t:n]}),even:he(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:he(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:he(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:he(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=r.pseudos.eq;for(t in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})r.pseudos[t]=fe(t);for(t in{submit:!0,reset:!0})r.pseudos[t]=pe(t);function ye(){}ye.prototype=r.filters=r.pseudos,r.setFilters=new ye,a=oe.tokenize=function(e,t){var n,i,o,a,s,u,l,c=k[e+" "];if(c)return t?0:c.slice(0);s=e,u=[],l=r.preFilter;while(s){n&&!(i=F.exec(s))||(i&&(s=s.slice(i[0].length)||s),u.push(o=[])),n=!1,(i=_.exec(s))&&(n=i.shift(),o.push({value:n,type:i[0].replace(B," ")}),s=s.slice(n.length));for(a in r.filter)!(i=V[a].exec(s))||l[a]&&!(i=l[a](i))||(n=i.shift(),o.push({value:n,type:a,matches:i}),s=s.slice(n.length));if(!n)break}return t?s.length:s?oe.error(e):k(e,u).slice(0)};function ve(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function me(e,t,n){var r=t.dir,i=t.next,o=i||r,a=n&&"parentNode"===o,s=C++;return t.first?function(t,n,i){while(t=t[r])if(1===t.nodeType||a)return e(t,n,i);return!1}:function(t,n,u){var l,c,f,p=[T,s];if(u){while(t=t[r])if((1===t.nodeType||a)&&e(t,n,u))return!0}else while(t=t[r])if(1===t.nodeType||a)if(f=t[b]||(t[b]={}),c=f[t.uniqueID]||(f[t.uniqueID]={}),i&&i===t.nodeName.toLowerCase())t=t[r]||t;else{if((l=c[o])&&l[0]===T&&l[1]===s)return p[2]=l[2];if(c[o]=p,p[2]=e(t,n,u))return!0}return!1}}function xe(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function be(e,t,n){for(var r=0,i=t.length;r<i;r++)oe(e,t[r],n);return n}function we(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Te(e,t,n,r,i,o){return r&&!r[b]&&(r=Te(r)),i&&!i[b]&&(i=Te(i,o)),se(function(o,a,s,u){var l,c,f,p=[],d=[],h=a.length,g=o||be(t||"*",s.nodeType?[s]:s,[]),y=!e||!o&&t?g:we(g,p,e,s,u),v=n?i||(o?e:h||r)?[]:a:y;if(n&&n(y,v,s,u),r){l=we(v,d),r(l,[],s,u),c=l.length;while(c--)(f=l[c])&&(v[d[c]]=!(y[d[c]]=f))}if(o){if(i||e){if(i){l=[],c=v.length;while(c--)(f=v[c])&&l.push(y[c]=f);i(null,v=[],l,u)}c=v.length;while(c--)(f=v[c])&&(l=i?O(o,f):p[c])>-1&&(o[l]=!(a[l]=f))}}else v=we(v===a?v.splice(h,v.length):v),i?i(null,a,v,u):L.apply(a,v)})}function Ce(e){for(var t,n,i,o=e.length,a=r.relative[e[0].type],s=a||r.relative[" "],u=a?1:0,c=me(function(e){return e===t},s,!0),f=me(function(e){return O(t,e)>-1},s,!0),p=[function(e,n,r){var i=!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):f(e,n,r));return t=null,i}];u<o;u++)if(n=r.relative[e[u].type])p=[me(xe(p),n)];else{if((n=r.filter[e[u].type].apply(null,e[u].matches))[b]){for(i=++u;i<o;i++)if(r.relative[e[i].type])break;return Te(u>1&&xe(p),u>1&&ve(e.slice(0,u-1).concat({value:" "===e[u-2].type?"*":""})).replace(B,"$1"),n,u<i&&Ce(e.slice(u,i)),i<o&&Ce(e=e.slice(i)),i<o&&ve(e))}p.push(n)}return xe(p)}function Ee(e,t){var n=t.length>0,i=e.length>0,o=function(o,a,s,u,c){var f,h,y,v=0,m="0",x=o&&[],b=[],w=l,C=o||i&&r.find.TAG("*",c),E=T+=null==w?1:Math.random()||.1,k=C.length;for(c&&(l=a===d||a||c);m!==k&&null!=(f=C[m]);m++){if(i&&f){h=0,a||f.ownerDocument===d||(p(f),s=!g);while(y=e[h++])if(y(f,a||d,s)){u.push(f);break}c&&(T=E)}n&&((f=!y&&f)&&v--,o&&x.push(f))}if(v+=m,n&&m!==v){h=0;while(y=t[h++])y(x,b,a,s);if(o){if(v>0)while(m--)x[m]||b[m]||(b[m]=j.call(u));b=we(b)}L.apply(u,b),c&&!o&&b.length>0&&v+t.length>1&&oe.uniqueSort(u)}return c&&(T=E,l=w),x};return n?se(o):o}return s=oe.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=a(e)),n=t.length;while(n--)(o=Ce(t[n]))[b]?r.push(o):i.push(o);(o=S(e,Ee(i,r))).selector=e}return o},u=oe.select=function(e,t,n,i){var o,u,l,c,f,p="function"==typeof e&&e,d=!i&&a(e=p.selector||e);if(n=n||[],1===d.length){if((u=d[0]=d[0].slice(0)).length>2&&"ID"===(l=u[0]).type&&9===t.nodeType&&g&&r.relative[u[1].type]){if(!(t=(r.find.ID(l.matches[0].replace(Z,ee),t)||[])[0]))return n;p&&(t=t.parentNode),e=e.slice(u.shift().value.length)}o=V.needsContext.test(e)?0:u.length;while(o--){if(l=u[o],r.relative[c=l.type])break;if((f=r.find[c])&&(i=f(l.matches[0].replace(Z,ee),K.test(u[0].type)&&ge(t.parentNode)||t))){if(u.splice(o,1),!(e=i.length&&ve(u)))return L.apply(n,i),n;break}}}return(p||s(e,d))(i,t,!g,n,!t||K.test(e)&&ge(t.parentNode)||t),n},n.sortStable=b.split("").sort(D).join("")===b,n.detectDuplicates=!!f,p(),n.sortDetached=ue(function(e){return 1&e.compareDocumentPosition(d.createElement("fieldset"))}),ue(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||le("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),n.attributes&&ue(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||le("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ue(function(e){return null==e.getAttribute("disabled")})||le(P,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),oe}(e);w.find=E,w.expr=E.selectors,w.expr[":"]=w.expr.pseudos,w.uniqueSort=w.unique=E.uniqueSort,w.text=E.getText,w.isXMLDoc=E.isXML,w.contains=E.contains,w.escapeSelector=E.escape;var k=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&w(e).is(n))break;r.push(e)}return r},S=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},D=w.expr.match.needsContext;function N(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var A=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,t,n){return g(t)?w.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?w.grep(e,function(e){return e===t!==n}):"string"!=typeof t?w.grep(e,function(e){return u.call(t,e)>-1!==n}):w.filter(t,e,n)}w.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?w.find.matchesSelector(r,e)?[r]:[]:w.find.matches(e,w.grep(t,function(e){return 1===e.nodeType}))},w.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(w(e).filter(function(){for(t=0;t<r;t++)if(w.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)w.find(e,i[t],n);return r>1?w.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&D.test(e)?w(e):e||[],!1).length}});var q,L=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(w.fn.init=function(e,t,n){var i,o;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(i="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:L.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof w?t[0]:t,w.merge(this,w.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:r,!0)),A.test(i[1])&&w.isPlainObject(t))for(i in t)g(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(o=r.getElementById(i[2]))&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):g(e)?void 0!==n.ready?n.ready(e):e(w):w.makeArray(e,this)}).prototype=w.fn,q=w(r);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};w.fn.extend({has:function(e){var t=w(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(w.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&w(e);if(!D.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?a.index(n)>-1:1===n.nodeType&&w.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?w.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?u.call(w(e),this[0]):u.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(w.uniqueSort(w.merge(this.get(),w(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}w.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return k(e,"parentNode")},parentsUntil:function(e,t,n){return k(e,"parentNode",n)},next:function(e){return P(e,"nextSibling")},prev:function(e){return P(e,"previousSibling")},nextAll:function(e){return k(e,"nextSibling")},prevAll:function(e){return k(e,"previousSibling")},nextUntil:function(e,t,n){return k(e,"nextSibling",n)},prevUntil:function(e,t,n){return k(e,"previousSibling",n)},siblings:function(e){return S((e.parentNode||{}).firstChild,e)},children:function(e){return S(e.firstChild)},contents:function(e){return N(e,"iframe")?e.contentDocument:(N(e,"template")&&(e=e.content||e),w.merge([],e.childNodes))}},function(e,t){w.fn[e]=function(n,r){var i=w.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=w.filter(r,i)),this.length>1&&(O[e]||w.uniqueSort(i),H.test(e)&&i.reverse()),this.pushStack(i)}});var M=/[^\x20\t\r\n\f]+/g;function R(e){var t={};return w.each(e.match(M)||[],function(e,n){t[n]=!0}),t}w.Callbacks=function(e){e="string"==typeof e?R(e):w.extend({},e);var t,n,r,i,o=[],a=[],s=-1,u=function(){for(i=i||e.once,r=t=!0;a.length;s=-1){n=a.shift();while(++s<o.length)!1===o[s].apply(n[0],n[1])&&e.stopOnFalse&&(s=o.length,n=!1)}e.memory||(n=!1),t=!1,i&&(o=n?[]:"")},l={add:function(){return o&&(n&&!t&&(s=o.length-1,a.push(n)),function t(n){w.each(n,function(n,r){g(r)?e.unique&&l.has(r)||o.push(r):r&&r.length&&"string"!==x(r)&&t(r)})}(arguments),n&&!t&&u()),this},remove:function(){return w.each(arguments,function(e,t){var n;while((n=w.inArray(t,o,n))>-1)o.splice(n,1),n<=s&&s--}),this},has:function(e){return e?w.inArray(e,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return i=a=[],o=n="",this},disabled:function(){return!o},lock:function(){return i=a=[],n||t||(o=n=""),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=[e,(n=n||[]).slice?n.slice():n],a.push(n),t||u()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l};function I(e){return e}function W(e){throw e}function $(e,t,n,r){var i;try{e&&g(i=e.promise)?i.call(e).done(t).fail(n):e&&g(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}w.extend({Deferred:function(t){var n=[["notify","progress",w.Callbacks("memory"),w.Callbacks("memory"),2],["resolve","done",w.Callbacks("once memory"),w.Callbacks("once memory"),0,"resolved"],["reject","fail",w.Callbacks("once memory"),w.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},"catch":function(e){return i.then(null,e)},pipe:function(){var e=arguments;return w.Deferred(function(t){w.each(n,function(n,r){var i=g(e[r[4]])&&e[r[4]];o[r[1]](function(){var e=i&&i.apply(this,arguments);e&&g(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+"With"](this,i?[e]:arguments)})}),e=null}).promise()},then:function(t,r,i){var o=0;function a(t,n,r,i){return function(){var s=this,u=arguments,l=function(){var e,l;if(!(t<o)){if((e=r.apply(s,u))===n.promise())throw new TypeError("Thenable self-resolution");l=e&&("object"==typeof e||"function"==typeof e)&&e.then,g(l)?i?l.call(e,a(o,n,I,i),a(o,n,W,i)):(o++,l.call(e,a(o,n,I,i),a(o,n,W,i),a(o,n,I,n.notifyWith))):(r!==I&&(s=void 0,u=[e]),(i||n.resolveWith)(s,u))}},c=i?l:function(){try{l()}catch(e){w.Deferred.exceptionHook&&w.Deferred.exceptionHook(e,c.stackTrace),t+1>=o&&(r!==W&&(s=void 0,u=[e]),n.rejectWith(s,u))}};t?c():(w.Deferred.getStackHook&&(c.stackTrace=w.Deferred.getStackHook()),e.setTimeout(c))}}return w.Deferred(function(e){n[0][3].add(a(0,e,g(i)?i:I,e.notifyWith)),n[1][3].add(a(0,e,g(t)?t:I)),n[2][3].add(a(0,e,g(r)?r:W))}).promise()},promise:function(e){return null!=e?w.extend(e,i):i}},o={};return w.each(n,function(e,t){var a=t[2],s=t[5];i[t[1]]=a.add,s&&a.add(function(){r=s},n[3-e][2].disable,n[3-e][3].disable,n[0][2].lock,n[0][3].lock),a.add(t[3].fire),o[t[0]]=function(){return o[t[0]+"With"](this===o?void 0:this,arguments),this},o[t[0]+"With"]=a.fireWith}),i.promise(o),t&&t.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),i=o.call(arguments),a=w.Deferred(),s=function(e){return function(n){r[e]=this,i[e]=arguments.length>1?o.call(arguments):n,--t||a.resolveWith(r,i)}};if(t<=1&&($(e,a.done(s(n)).resolve,a.reject,!t),"pending"===a.state()||g(i[n]&&i[n].then)))return a.then();while(n--)$(i[n],s(n),a.reject);return a.promise()}});var B=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;w.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&B.test(t.name)&&e.console.warn("jQuery.Deferred exception: "+t.message,t.stack,n)},w.readyException=function(t){e.setTimeout(function(){throw t})};var F=w.Deferred();w.fn.ready=function(e){return F.then(e)["catch"](function(e){w.readyException(e)}),this},w.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--w.readyWait:w.isReady)||(w.isReady=!0,!0!==e&&--w.readyWait>0||F.resolveWith(r,[w]))}}),w.ready.then=F.then;function _(){r.removeEventListener("DOMContentLoaded",_),e.removeEventListener("load",_),w.ready()}"complete"===r.readyState||"loading"!==r.readyState&&!r.documentElement.doScroll?e.setTimeout(w.ready):(r.addEventListener("DOMContentLoaded",_),e.addEventListener("load",_));var z=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===x(n)){i=!0;for(s in n)z(e,t,s,n[s],!0,o,a)}else if(void 0!==r&&(i=!0,g(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(w(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},X=/^-ms-/,U=/-([a-z])/g;function V(e,t){return t.toUpperCase()}function G(e){return e.replace(X,"ms-").replace(U,V)}var Y=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function Q(){this.expando=w.expando+Q.uid++}Q.uid=1,Q.prototype={cache:function(e){var t=e[this.expando];return t||(t={},Y(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[G(t)]=n;else for(r in t)i[G(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][G(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(G):(t=G(t))in r?[t]:t.match(M)||[]).length;while(n--)delete r[t[n]]}(void 0===t||w.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!w.isEmptyObject(t)}};var J=new Q,K=new Q,Z=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,ee=/[A-Z]/g;function te(e){return"true"===e||"false"!==e&&("null"===e?null:e===+e+""?+e:Z.test(e)?JSON.parse(e):e)}function ne(e,t,n){var r;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(ee,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n=te(n)}catch(e){}K.set(e,t,n)}else n=void 0;return n}w.extend({hasData:function(e){return K.hasData(e)||J.hasData(e)},data:function(e,t,n){return K.access(e,t,n)},removeData:function(e,t){K.remove(e,t)},_data:function(e,t,n){return J.access(e,t,n)},_removeData:function(e,t){J.remove(e,t)}}),w.fn.extend({data:function(e,t){var n,r,i,o=this[0],a=o&&o.attributes;if(void 0===e){if(this.length&&(i=K.get(o),1===o.nodeType&&!J.get(o,"hasDataAttrs"))){n=a.length;while(n--)a[n]&&0===(r=a[n].name).indexOf("data-")&&(r=G(r.slice(5)),ne(o,r,i[r]));J.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof e?this.each(function(){K.set(this,e)}):z(this,function(t){var n;if(o&&void 0===t){if(void 0!==(n=K.get(o,e)))return n;if(void 0!==(n=ne(o,e)))return n}else this.each(function(){K.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){K.remove(this,e)})}}),w.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=J.get(e,t),n&&(!r||Array.isArray(n)?r=J.access(e,t,w.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=w.queue(e,t),r=n.length,i=n.shift(),o=w._queueHooks(e,t),a=function(){w.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return J.get(e,n)||J.access(e,n,{empty:w.Callbacks("once memory").add(function(){J.remove(e,[t+"queue",n])})})}}),w.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length<n?w.queue(this[0],e):void 0===t?this:this.each(function(){var n=w.queue(this,e,t);w._queueHooks(this,e),"fx"===e&&"inprogress"!==n[0]&&w.dequeue(this,e)})},dequeue:function(e){return this.each(function(){w.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=w.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=J.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var re=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ie=new RegExp("^(?:([+-])=|)("+re+")([a-z%]*)$","i"),oe=["Top","Right","Bottom","Left"],ae=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&w.contains(e.ownerDocument,e)&&"none"===w.css(e,"display")},se=function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i};function ue(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return w.css(e,t,"")},u=s(),l=n&&n[3]||(w.cssNumber[t]?"":"px"),c=(w.cssNumber[t]||"px"!==l&&+u)&&ie.exec(w.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)w.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,w.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var le={};function ce(e){var t,n=e.ownerDocument,r=e.nodeName,i=le[r];return i||(t=n.body.appendChild(n.createElement(r)),i=w.css(t,"display"),t.parentNode.removeChild(t),"none"===i&&(i="block"),le[r]=i,i)}function fe(e,t){for(var n,r,i=[],o=0,a=e.length;o<a;o++)(r=e[o]).style&&(n=r.style.display,t?("none"===n&&(i[o]=J.get(r,"display")||null,i[o]||(r.style.display="")),""===r.style.display&&ae(r)&&(i[o]=ce(r))):"none"!==n&&(i[o]="none",J.set(r,"display",n)));for(o=0;o<a;o++)null!=i[o]&&(e[o].style.display=i[o]);return e}w.fn.extend({show:function(){return fe(this,!0)},hide:function(){return fe(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){ae(this)?w(this).show():w(this).hide()})}});var pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ge.optgroup=ge.option,ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td;function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&N(e,t)?w.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n<r;n++)J.set(e[n],"globalEval",!t||J.get(t[n],"globalEval"))}var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===x(o))w.merge(p,o.nodeType?[o]:o);else if(me.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+w.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;w.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));f.textContent="",d=0;while(o=p[d++])if(r&&w.inArray(o,r)>-1)i&&i.push(o);else if(l=w.contains(o.ownerDocument,o),a=ye(f.appendChild(o),"script"),l&&ve(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}!function(){var e=r.createDocumentFragment().appendChild(r.createElement("div")),t=r.createElement("input");t.setAttribute("type","radio"),t.setAttribute("checked","checked"),t.setAttribute("name","t"),e.appendChild(t),h.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,e.innerHTML="<textarea>x</textarea>",h.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue}();var be=r.documentElement,we=/^key/,Te=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function Ee(){return!0}function ke(){return!1}function Se(){try{return r.activeElement}catch(e){}}function De(e,t,n,r,i,o){var a,s;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=void 0);for(s in t)De(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=ke;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return w().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=w.guid++)),e.each(function(){w.event.add(this,t,i,r,n)})}w.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.get(e);if(y){n.handler&&(n=(o=n).handler,i=o.selector),i&&w.find.matchesSelector(be,i),n.guid||(n.guid=w.guid++),(u=y.events)||(u=y.events={}),(a=y.handle)||(a=y.handle=function(t){return"undefined"!=typeof w&&w.event.triggered!==t.type?w.event.dispatch.apply(e,arguments):void 0}),l=(t=(t||"").match(M)||[""]).length;while(l--)d=g=(s=Ce.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=w.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=w.event.special[d]||{},c=w.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&w.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,a)||e.addEventListener&&e.addEventListener(d,a)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),w.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.hasData(e)&&J.get(e);if(y&&(u=y.events)){l=(t=(t||"").match(M)||[""]).length;while(l--)if(s=Ce.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){f=w.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,y.handle)||w.removeEvent(e,d,y.handle),delete u[d])}else for(d in u)w.event.remove(e,d+t[l],n,r,!0);w.isEmptyObject(u)&&J.remove(e,"handle events")}},dispatch:function(e){var t=w.event.fix(e),n,r,i,o,a,s,u=new Array(arguments.length),l=(J.get(this,"events")||{})[t.type]||[],c=w.event.special[t.type]||{};for(u[0]=t,n=1;n<arguments.length;n++)u[n]=arguments[n];if(t.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,t)){s=w.event.handlers.call(this,t,l),n=0;while((o=s[n++])&&!t.isPropagationStopped()){t.currentTarget=o.elem,r=0;while((a=o.handlers[r++])&&!t.isImmediatePropagationStopped())t.rnamespace&&!t.rnamespace.test(a.namespace)||(t.handleObj=a,t.data=a.data,void 0!==(i=((w.event.special[a.origType]||{}).handle||a.handler).apply(o.elem,u))&&!1===(t.result=i)&&(t.preventDefault(),t.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,t),t.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&e.button>=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?w(i,this).index(l)>-1:w.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(e,t){Object.defineProperty(w.Event.prototype,e,{enumerable:!0,configurable:!0,get:g(t)?function(){if(this.originalEvent)return t(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[e]},set:function(t){Object.defineProperty(this,e,{enumerable:!0,configurable:!0,writable:!0,value:t})}})},fix:function(e){return e[w.expando]?e:new w.Event(e)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==Se()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===Se()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&N(this,"input"))return this.click(),!1},_default:function(e){return N(e.target,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},w.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},w.Event=function(e,t){if(!(this instanceof w.Event))return new w.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?Ee:ke,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&w.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[w.expando]=!0},w.Event.prototype={constructor:w.Event,isDefaultPrevented:ke,isPropagationStopped:ke,isImmediatePropagationStopped:ke,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=Ee,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=Ee,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=Ee,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},w.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&we.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&Te.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},w.event.addProp),w.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,t){w.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return i&&(i===r||w.contains(r,i))||(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),w.fn.extend({on:function(e,t,n,r){return De(this,e,t,n,r)},one:function(e,t,n,r){return De(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,w(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=ke),this.each(function(){w.event.remove(this,e,n,t)})}});var Ne=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,Ae=/<script|<style|<link/i,je=/checked\s*(?:[^=]|=\s*.checked.)/i,qe=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Le(e,t){return N(e,"table")&&N(11!==t.nodeType?t:t.firstChild,"tr")?w(e).children("tbody")[0]||e:e}function He(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Oe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Pe(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(J.hasData(e)&&(o=J.access(e),a=J.set(t,o),l=o.events)){delete a.handle,a.events={};for(i in l)for(n=0,r=l[i].length;n<r;n++)w.event.add(t,i,l[i][n])}K.hasData(e)&&(s=K.access(e),u=w.extend({},s),K.set(t,u))}}function Me(e,t){var n=t.nodeName.toLowerCase();"input"===n&&pe.test(e.type)?t.checked=e.checked:"input"!==n&&"textarea"!==n||(t.defaultValue=e.defaultValue)}function Re(e,t,n,r){t=a.apply([],t);var i,o,s,u,l,c,f=0,p=e.length,d=p-1,y=t[0],v=g(y);if(v||p>1&&"string"==typeof y&&!h.checkClone&&je.test(y))return e.each(function(i){var o=e.eq(i);v&&(t[0]=y.call(this,i,o.html())),Re(o,t,n,r)});if(p&&(i=xe(t,e[0].ownerDocument,!1,e,r),o=i.firstChild,1===i.childNodes.length&&(i=o),o||r)){for(u=(s=w.map(ye(i,"script"),He)).length;f<p;f++)l=i,f!==d&&(l=w.clone(l,!0,!0),u&&w.merge(s,ye(l,"script"))),n.call(e[f],l,f);if(u)for(c=s[s.length-1].ownerDocument,w.map(s,Oe),f=0;f<u;f++)l=s[f],he.test(l.type||"")&&!J.access(l,"globalEval")&&w.contains(c,l)&&(l.src&&"module"!==(l.type||"").toLowerCase()?w._evalUrl&&w._evalUrl(l.src):m(l.textContent.replace(qe,""),c,l))}return e}function Ie(e,t,n){for(var r,i=t?w.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||w.cleanData(ye(r)),r.parentNode&&(n&&w.contains(r.ownerDocument,r)&&ve(ye(r,"script")),r.parentNode.removeChild(r));return e}w.extend({htmlPrefilter:function(e){return e.replace(Ne,"<$1></$2>")},clone:function(e,t,n){var r,i,o,a,s=e.cloneNode(!0),u=w.contains(e.ownerDocument,e);if(!(h.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||w.isXMLDoc(e)))for(a=ye(s),r=0,i=(o=ye(e)).length;r<i;r++)Me(o[r],a[r]);if(t)if(n)for(o=o||ye(e),a=a||ye(s),r=0,i=o.length;r<i;r++)Pe(o[r],a[r]);else Pe(e,s);return(a=ye(s,"script")).length>0&&ve(a,!u&&ye(e,"script")),s},cleanData:function(e){for(var t,n,r,i=w.event.special,o=0;void 0!==(n=e[o]);o++)if(Y(n)){if(t=n[J.expando]){if(t.events)for(r in t.events)i[r]?w.event.remove(n,r):w.removeEvent(n,r,t.handle);n[J.expando]=void 0}n[K.expando]&&(n[K.expando]=void 0)}}}),w.fn.extend({detach:function(e){return Ie(this,e,!0)},remove:function(e){return Ie(this,e)},text:function(e){return z(this,function(e){return void 0===e?w.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Re(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Le(this,e).appendChild(e)})},prepend:function(){return Re(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Le(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(w.cleanData(ye(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return w.clone(this,e,t)})},html:function(e){return z(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ae.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=w.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(w.cleanData(ye(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=[];return Re(this,arguments,function(t){var n=this.parentNode;w.inArray(this,e)<0&&(w.cleanData(ye(this)),n&&n.replaceChild(t,this))},e)}}),w.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){w.fn[e]=function(e){for(var n,r=[],i=w(e),o=i.length-1,a=0;a<=o;a++)n=a===o?this:this.clone(!0),w(i[a])[t](n),s.apply(r,n.get());return this.pushStack(r)}});var We=new RegExp("^("+re+")(?!px)[a-z%]+$","i"),$e=function(t){var n=t.ownerDocument.defaultView;return n&&n.opener||(n=e),n.getComputedStyle(t)},Be=new RegExp(oe.join("|"),"i");!function(){function t(){if(c){l.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",c.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",be.appendChild(l).appendChild(c);var t=e.getComputedStyle(c);i="1%"!==t.top,u=12===n(t.marginLeft),c.style.right="60%",s=36===n(t.right),o=36===n(t.width),c.style.position="absolute",a=36===c.offsetWidth||"absolute",be.removeChild(l),c=null}}function n(e){return Math.round(parseFloat(e))}var i,o,a,s,u,l=r.createElement("div"),c=r.createElement("div");c.style&&(c.style.backgroundClip="content-box",c.cloneNode(!0).style.backgroundClip="",h.clearCloneStyle="content-box"===c.style.backgroundClip,w.extend(h,{boxSizingReliable:function(){return t(),o},pixelBoxStyles:function(){return t(),s},pixelPosition:function(){return t(),i},reliableMarginLeft:function(){return t(),u},scrollboxSize:function(){return t(),a}}))}();function Fe(e,t,n){var r,i,o,a,s=e.style;return(n=n||$e(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||w.contains(e.ownerDocument,e)||(a=w.style(e,t)),!h.pixelBoxStyles()&&We.test(a)&&Be.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function _e(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}var ze=/^(none|table(?!-c[ea]).+)/,Xe=/^--/,Ue={position:"absolute",visibility:"hidden",display:"block"},Ve={letterSpacing:"0",fontWeight:"400"},Ge=["Webkit","Moz","ms"],Ye=r.createElement("div").style;function Qe(e){if(e in Ye)return e;var t=e[0].toUpperCase()+e.slice(1),n=Ge.length;while(n--)if((e=Ge[n]+t)in Ye)return e}function Je(e){var t=w.cssProps[e];return t||(t=w.cssProps[e]=Qe(e)||e),t}function Ke(e,t,n){var r=ie.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function Ze(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=w.css(e,n+oe[a],!0,i)),r?("content"===n&&(u-=w.css(e,"padding"+oe[a],!0,i)),"margin"!==n&&(u-=w.css(e,"border"+oe[a]+"Width",!0,i))):(u+=w.css(e,"padding"+oe[a],!0,i),"padding"!==n?u+=w.css(e,"border"+oe[a]+"Width",!0,i):s+=w.css(e,"border"+oe[a]+"Width",!0,i));return!r&&o>=0&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))),u}function et(e,t,n){var r=$e(e),i=Fe(e,t,r),o="border-box"===w.css(e,"boxSizing",!1,r),a=o;if(We.test(i)){if(!n)return i;i="auto"}return a=a&&(h.boxSizingReliable()||i===e.style[t]),("auto"===i||!parseFloat(i)&&"inline"===w.css(e,"display",!1,r))&&(i=e["offset"+t[0].toUpperCase()+t.slice(1)],a=!0),(i=parseFloat(i)||0)+Ze(e,t,n||(o?"border":"content"),a,r,i)+"px"}w.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Fe(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=G(t),u=Xe.test(t),l=e.style;if(u||(t=Je(s)),a=w.cssHooks[t]||w.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"==(o=typeof n)&&(i=ie.exec(n))&&i[1]&&(n=ue(e,t,i),o="number"),null!=n&&n===n&&("number"===o&&(n+=i&&i[3]||(w.cssNumber[s]?"":"px")),h.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=G(t);return Xe.test(t)||(t=Je(s)),(a=w.cssHooks[t]||w.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Fe(e,t,r)),"normal"===i&&t in Ve&&(i=Ve[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),w.each(["height","width"],function(e,t){w.cssHooks[t]={get:function(e,n,r){if(n)return!ze.test(w.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?et(e,t,r):se(e,Ue,function(){return et(e,t,r)})},set:function(e,n,r){var i,o=$e(e),a="border-box"===w.css(e,"boxSizing",!1,o),s=r&&Ze(e,t,r,a,o);return a&&h.scrollboxSize()===o.position&&(s-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-Ze(e,t,"border",!1,o)-.5)),s&&(i=ie.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=w.css(e,t)),Ke(e,n,s)}}}),w.cssHooks.marginLeft=_e(h.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Fe(e,"marginLeft"))||e.getBoundingClientRect().left-se(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),w.each({margin:"",padding:"",border:"Width"},function(e,t){w.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+oe[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(w.cssHooks[e+t].set=Ke)}),w.fn.extend({css:function(e,t){return z(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=$e(e),i=t.length;a<i;a++)o[t[a]]=w.css(e,t[a],!1,r);return o}return void 0!==n?w.style(e,t,n):w.css(e,t)},e,t,arguments.length>1)}});function tt(e,t,n,r,i){return new tt.prototype.init(e,t,n,r,i)}w.Tween=tt,tt.prototype={constructor:tt,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||w.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(w.cssNumber[n]?"":"px")},cur:function(){var e=tt.propHooks[this.prop];return e&&e.get?e.get(this):tt.propHooks._default.get(this)},run:function(e){var t,n=tt.propHooks[this.prop];return this.options.duration?this.pos=t=w.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):tt.propHooks._default.set(this),this}},tt.prototype.init.prototype=tt.prototype,tt.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=w.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){w.fx.step[e.prop]?w.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[w.cssProps[e.prop]]&&!w.cssHooks[e.prop]?e.elem[e.prop]=e.now:w.style(e.elem,e.prop,e.now+e.unit)}}},tt.propHooks.scrollTop=tt.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},w.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},w.fx=tt.prototype.init,w.fx.step={};var nt,rt,it=/^(?:toggle|show|hide)$/,ot=/queueHooks$/;function at(){rt&&(!1===r.hidden&&e.requestAnimationFrame?e.requestAnimationFrame(at):e.setTimeout(at,w.fx.interval),w.fx.tick())}function st(){return e.setTimeout(function(){nt=void 0}),nt=Date.now()}function ut(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=oe[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function lt(e,t,n){for(var r,i=(pt.tweeners[t]||[]).concat(pt.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function ct(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&ae(e),y=J.get(e,"fxshow");n.queue||(null==(a=w._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,w.queue(e,"fx").length||a.empty.fire()})}));for(r in t)if(i=t[r],it.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!y||void 0===y[r])continue;g=!0}d[r]=y&&y[r]||w.style(e,r)}if((u=!w.isEmptyObject(t))||!w.isEmptyObject(d)){f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=y&&y.display)&&(l=J.get(e,"display")),"none"===(c=w.css(e,"display"))&&(l?c=l:(fe([e],!0),l=e.style.display||l,c=w.css(e,"display"),fe([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===w.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1;for(r in d)u||(y?"hidden"in y&&(g=y.hidden):y=J.access(e,"fxshow",{display:l}),o&&(y.hidden=!g),g&&fe([e],!0),p.done(function(){g||fe([e]),J.remove(e,"fxshow");for(r in d)w.style(e,r,d[r])})),u=lt(g?y[r]:0,r,p),r in y||(y[r]=u.start,g&&(u.end=u.start,u.start=0))}}function ft(e,t){var n,r,i,o,a;for(n in e)if(r=G(n),i=t[r],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=w.cssHooks[r])&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}function pt(e,t,n){var r,i,o=0,a=pt.prefilters.length,s=w.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;for(var t=nt||st(),n=Math.max(0,l.startTime+l.duration-t),r=1-(n/l.duration||0),o=0,a=l.tweens.length;o<a;o++)l.tweens[o].run(r);return s.notifyWith(e,[l,r,n]),r<1&&a?n:(a||s.notifyWith(e,[l,1,0]),s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:w.extend({},t),opts:w.extend(!0,{specialEasing:{},easing:w.easing._default},n),originalProperties:t,originalOptions:n,startTime:nt||st(),duration:n.duration,tweens:[],createTween:function(t,n){var r=w.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;n<r;n++)l.tweens[n].run(1);return t?(s.notifyWith(e,[l,1,0]),s.resolveWith(e,[l,t])):s.rejectWith(e,[l,t]),this}}),c=l.props;for(ft(c,l.opts.specialEasing);o<a;o++)if(r=pt.prefilters[o].call(l,e,c,l.opts))return g(r.stop)&&(w._queueHooks(l.elem,l.opts.queue).stop=r.stop.bind(r)),r;return w.map(c,lt,l),g(l.opts.start)&&l.opts.start.call(e,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),w.fx.timer(w.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l}w.Animation=w.extend(pt,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return ue(n.elem,e,ie.exec(t),n),n}]},tweener:function(e,t){g(e)?(t=e,e=["*"]):e=e.match(M);for(var n,r=0,i=e.length;r<i;r++)n=e[r],pt.tweeners[n]=pt.tweeners[n]||[],pt.tweeners[n].unshift(t)},prefilters:[ct],prefilter:function(e,t){t?pt.prefilters.unshift(e):pt.prefilters.push(e)}}),w.speed=function(e,t,n){var r=e&&"object"==typeof e?w.extend({},e):{complete:n||!n&&t||g(e)&&e,duration:e,easing:n&&t||t&&!g(t)&&t};return w.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in w.fx.speeds?r.duration=w.fx.speeds[r.duration]:r.duration=w.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){g(r.old)&&r.old.call(this),r.queue&&w.dequeue(this,r.queue)},r},w.fn.extend({fadeTo:function(e,t,n,r){return this.filter(ae).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=w.isEmptyObject(e),o=w.speed(t,n,r),a=function(){var t=pt(this,w.extend({},e),o);(i||J.get(this,"finish"))&&t.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return"string"!=typeof e&&(n=t,t=e,e=void 0),t&&!1!==e&&this.queue(e||"fx",[]),this.each(function(){var t=!0,i=null!=e&&e+"queueHooks",o=w.timers,a=J.get(this);if(i)a[i]&&a[i].stop&&r(a[i]);else for(i in a)a[i]&&a[i].stop&&ot.test(i)&&r(a[i]);for(i=o.length;i--;)o[i].elem!==this||null!=e&&o[i].queue!==e||(o[i].anim.stop(n),t=!1,o.splice(i,1));!t&&n||w.dequeue(this,e)})},finish:function(e){return!1!==e&&(e=e||"fx"),this.each(function(){var t,n=J.get(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=w.timers,a=r?r.length:0;for(n.finish=!0,w.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;t<a;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}}),w.each(["toggle","show","hide"],function(e,t){var n=w.fn[t];w.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ut(t,!0),e,r,i)}}),w.each({slideDown:ut("show"),slideUp:ut("hide"),slideToggle:ut("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){w.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),w.timers=[],w.fx.tick=function(){var e,t=0,n=w.timers;for(nt=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||w.fx.stop(),nt=void 0},w.fx.timer=function(e){w.timers.push(e),w.fx.start()},w.fx.interval=13,w.fx.start=function(){rt||(rt=!0,at())},w.fx.stop=function(){rt=null},w.fx.speeds={slow:600,fast:200,_default:400},w.fn.delay=function(t,n){return t=w.fx?w.fx.speeds[t]||t:t,n=n||"fx",this.queue(n,function(n,r){var i=e.setTimeout(n,t);r.stop=function(){e.clearTimeout(i)}})},function(){var e=r.createElement("input"),t=r.createElement("select").appendChild(r.createElement("option"));e.type="checkbox",h.checkOn=""!==e.value,h.optSelected=t.selected,(e=r.createElement("input")).value="t",e.type="radio",h.radioValue="t"===e.value}();var dt,ht=w.expr.attrHandle;w.fn.extend({attr:function(e,t){return z(this,w.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){w.removeAttr(this,e)})}}),w.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?w.prop(e,t,n):(1===o&&w.isXMLDoc(e)||(i=w.attrHooks[t.toLowerCase()]||(w.expr.match.bool.test(t)?dt:void 0)),void 0!==n?null===n?void w.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=w.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!h.radioValue&&"radio"===t&&N(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(M);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),dt={set:function(e,t,n){return!1===t?w.removeAttr(e,n):e.setAttribute(n,n),n}},w.each(w.expr.match.bool.source.match(/\w+/g),function(e,t){var n=ht[t]||w.find.attr;ht[t]=function(e,t,r){var i,o,a=t.toLowerCase();return r||(o=ht[a],ht[a]=i,i=null!=n(e,t,r)?a:null,ht[a]=o),i}});var gt=/^(?:input|select|textarea|button)$/i,yt=/^(?:a|area)$/i;w.fn.extend({prop:function(e,t){return z(this,w.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[w.propFix[e]||e]})}}),w.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&w.isXMLDoc(e)||(t=w.propFix[t]||t,i=w.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=w.find.attr(e,"tabindex");return t?parseInt(t,10):gt.test(e.nodeName)||yt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),h.optSelected||(w.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),w.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){w.propFix[this.toLowerCase()]=this});function vt(e){return(e.match(M)||[]).join(" ")}function mt(e){return e.getAttribute&&e.getAttribute("class")||""}function xt(e){return Array.isArray(e)?e:"string"==typeof e?e.match(M)||[]:[]}w.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).addClass(e.call(this,t,mt(this)))});if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).removeClass(e.call(this,t,mt(this)))});if(!arguments.length)return this.attr("class","");if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])while(r.indexOf(" "+o+" ")>-1)r=r.replace(" "+o+" "," ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(e,t){var n=typeof e,r="string"===n||Array.isArray(e);return"boolean"==typeof t&&r?t?this.addClass(e):this.removeClass(e):g(e)?this.each(function(n){w(this).toggleClass(e.call(this,n,mt(this),t),t)}):this.each(function(){var t,i,o,a;if(r){i=0,o=w(this),a=xt(e);while(t=a[i++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else void 0!==e&&"boolean"!==n||((t=mt(this))&&J.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":J.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&(" "+vt(mt(n))+" ").indexOf(t)>-1)return!0;return!1}});var bt=/\r/g;w.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=g(e),this.each(function(n){var i;1===this.nodeType&&(null==(i=r?e.call(this,n,w(this).val()):e)?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=w.map(i,function(e){return null==e?"":e+""})),(t=w.valHooks[this.type]||w.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))});if(i)return(t=w.valHooks[i.type]||w.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:"string"==typeof(n=i.value)?n.replace(bt,""):null==n?"":n}}}),w.extend({valHooks:{option:{get:function(e){var t=w.find.attr(e,"value");return null!=t?t:vt(w.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!N(n.parentNode,"optgroup"))){if(t=w(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=w.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=w.inArray(w.valHooks.option.get(r),o)>-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),w.each(["radio","checkbox"],function(){w.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=w.inArray(w(e).val(),t)>-1}},h.checkOn||(w.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),h.focusin="onfocusin"in e;var wt=/^(?:focusinfocus|focusoutblur)$/,Tt=function(e){e.stopPropagation()};w.extend(w.event,{trigger:function(t,n,i,o){var a,s,u,l,c,p,d,h,v=[i||r],m=f.call(t,"type")?t.type:t,x=f.call(t,"namespace")?t.namespace.split("."):[];if(s=h=u=i=i||r,3!==i.nodeType&&8!==i.nodeType&&!wt.test(m+w.event.triggered)&&(m.indexOf(".")>-1&&(m=(x=m.split(".")).shift(),x.sort()),c=m.indexOf(":")<0&&"on"+m,t=t[w.expando]?t:new w.Event(m,"object"==typeof t&&t),t.isTrigger=o?2:3,t.namespace=x.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+x.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=i),n=null==n?[t]:w.makeArray(n,[t]),d=w.event.special[m]||{},o||!d.trigger||!1!==d.trigger.apply(i,n))){if(!o&&!d.noBubble&&!y(i)){for(l=d.delegateType||m,wt.test(l+m)||(s=s.parentNode);s;s=s.parentNode)v.push(s),u=s;u===(i.ownerDocument||r)&&v.push(u.defaultView||u.parentWindow||e)}a=0;while((s=v[a++])&&!t.isPropagationStopped())h=s,t.type=a>1?l:d.bindType||m,(p=(J.get(s,"events")||{})[t.type]&&J.get(s,"handle"))&&p.apply(s,n),(p=c&&s[c])&&p.apply&&Y(s)&&(t.result=p.apply(s,n),!1===t.result&&t.preventDefault());return t.type=m,o||t.isDefaultPrevented()||d._default&&!1!==d._default.apply(v.pop(),n)||!Y(i)||c&&g(i[m])&&!y(i)&&((u=i[c])&&(i[c]=null),w.event.triggered=m,t.isPropagationStopped()&&h.addEventListener(m,Tt),i[m](),t.isPropagationStopped()&&h.removeEventListener(m,Tt),w.event.triggered=void 0,u&&(i[c]=u)),t.result}},simulate:function(e,t,n){var r=w.extend(new w.Event,n,{type:e,isSimulated:!0});w.event.trigger(r,null,t)}}),w.fn.extend({trigger:function(e,t){return this.each(function(){w.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return w.event.trigger(e,t,n,!0)}}),h.focusin||w.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){w.event.simulate(t,e.target,w.event.fix(e))};w.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=J.access(r,t);i||r.addEventListener(e,n,!0),J.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=J.access(r,t)-1;i?J.access(r,t,i):(r.removeEventListener(e,n,!0),J.remove(r,t))}}});var Ct=e.location,Et=Date.now(),kt=/\?/;w.parseXML=function(t){var n;if(!t||"string"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,"text/xml")}catch(e){n=void 0}return n&&!n.getElementsByTagName("parsererror").length||w.error("Invalid XML: "+t),n};var St=/\[\]$/,Dt=/\r?\n/g,Nt=/^(?:submit|button|image|reset|file)$/i,At=/^(?:input|select|textarea|keygen)/i;function jt(e,t,n,r){var i;if(Array.isArray(t))w.each(t,function(t,i){n||St.test(e)?r(e,i):jt(e+"["+("object"==typeof i&&null!=i?t:"")+"]",i,n,r)});else if(n||"object"!==x(t))r(e,t);else for(i in t)jt(e+"["+i+"]",t[i],n,r)}w.param=function(e,t){var n,r=[],i=function(e,t){var n=g(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(Array.isArray(e)||e.jquery&&!w.isPlainObject(e))w.each(e,function(){i(this.name,this.value)});else for(n in e)jt(n,e[n],t,i);return r.join("&")},w.fn.extend({serialize:function(){return w.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=w.prop(this,"elements");return e?w.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!w(this).is(":disabled")&&At.test(this.nodeName)&&!Nt.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=w(this).val();return null==n?null:Array.isArray(n)?w.map(n,function(e){return{name:t.name,value:e.replace(Dt,"\r\n")}}):{name:t.name,value:n.replace(Dt,"\r\n")}}).get()}});var qt=/%20/g,Lt=/#.*$/,Ht=/([?&])_=[^&]*/,Ot=/^(.*?):[ \t]*([^\r\n]*)$/gm,Pt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Mt=/^(?:GET|HEAD)$/,Rt=/^\/\//,It={},Wt={},$t="*/".concat("*"),Bt=r.createElement("a");Bt.href=Ct.href;function Ft(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(M)||[];if(g(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function _t(e,t,n,r){var i={},o=e===Wt;function a(s){var u;return i[s]=!0,w.each(e[s]||[],function(e,s){var l=s(t,n,r);return"string"!=typeof l||o||i[l]?o?!(u=l):void 0:(t.dataTypes.unshift(l),a(l),!1)}),u}return a(t.dataTypes[0])||!i["*"]&&a("*")}function zt(e,t){var n,r,i=w.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&w.extend(!0,e,r),e}function Xt(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}function Ut(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}w.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ct.href,type:"GET",isLocal:Pt.test(Ct.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":$t,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":w.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?zt(zt(e,w.ajaxSettings),t):zt(w.ajaxSettings,e)},ajaxPrefilter:Ft(It),ajaxTransport:Ft(Wt),ajax:function(t,n){"object"==typeof t&&(n=t,t=void 0),n=n||{};var i,o,a,s,u,l,c,f,p,d,h=w.ajaxSetup({},n),g=h.context||h,y=h.context&&(g.nodeType||g.jquery)?w(g):w.event,v=w.Deferred(),m=w.Callbacks("once memory"),x=h.statusCode||{},b={},T={},C="canceled",E={readyState:0,getResponseHeader:function(e){var t;if(c){if(!s){s={};while(t=Ot.exec(a))s[t[1].toLowerCase()]=t[2]}t=s[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return c?a:null},setRequestHeader:function(e,t){return null==c&&(e=T[e.toLowerCase()]=T[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==c&&(h.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)E.always(e[E.status]);else for(t in e)x[t]=[x[t],e[t]];return this},abort:function(e){var t=e||C;return i&&i.abort(t),k(0,t),this}};if(v.promise(E),h.url=((t||h.url||Ct.href)+"").replace(Rt,Ct.protocol+"//"),h.type=n.method||n.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(M)||[""],null==h.crossDomain){l=r.createElement("a");try{l.href=h.url,l.href=l.href,h.crossDomain=Bt.protocol+"//"+Bt.host!=l.protocol+"//"+l.host}catch(e){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=w.param(h.data,h.traditional)),_t(It,h,n,E),c)return E;(f=w.event&&h.global)&&0==w.active++&&w.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!Mt.test(h.type),o=h.url.replace(Lt,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(qt,"+")):(d=h.url.slice(o.length),h.data&&(h.processData||"string"==typeof h.data)&&(o+=(kt.test(o)?"&":"?")+h.data,delete h.data),!1===h.cache&&(o=o.replace(Ht,"$1"),d=(kt.test(o)?"&":"?")+"_="+Et+++d),h.url=o+d),h.ifModified&&(w.lastModified[o]&&E.setRequestHeader("If-Modified-Since",w.lastModified[o]),w.etag[o]&&E.setRequestHeader("If-None-Match",w.etag[o])),(h.data&&h.hasContent&&!1!==h.contentType||n.contentType)&&E.setRequestHeader("Content-Type",h.contentType),E.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+$t+"; q=0.01":""):h.accepts["*"]);for(p in h.headers)E.setRequestHeader(p,h.headers[p]);if(h.beforeSend&&(!1===h.beforeSend.call(g,E,h)||c))return E.abort();if(C="abort",m.add(h.complete),E.done(h.success),E.fail(h.error),i=_t(Wt,h,n,E)){if(E.readyState=1,f&&y.trigger("ajaxSend",[E,h]),c)return E;h.async&&h.timeout>0&&(u=e.setTimeout(function(){E.abort("timeout")},h.timeout));try{c=!1,i.send(b,k)}catch(e){if(c)throw e;k(-1,e)}}else k(-1,"No Transport");function k(t,n,r,s){var l,p,d,b,T,C=n;c||(c=!0,u&&e.clearTimeout(u),i=void 0,a=s||"",E.readyState=t>0?4:0,l=t>=200&&t<300||304===t,r&&(b=Xt(h,E,r)),b=Ut(h,b,E,l),l?(h.ifModified&&((T=E.getResponseHeader("Last-Modified"))&&(w.lastModified[o]=T),(T=E.getResponseHeader("etag"))&&(w.etag[o]=T)),204===t||"HEAD"===h.type?C="nocontent":304===t?C="notmodified":(C=b.state,p=b.data,l=!(d=b.error))):(d=C,!t&&C||(C="error",t<0&&(t=0))),E.status=t,E.statusText=(n||C)+"",l?v.resolveWith(g,[p,C,E]):v.rejectWith(g,[E,C,d]),E.statusCode(x),x=void 0,f&&y.trigger(l?"ajaxSuccess":"ajaxError",[E,h,l?p:d]),m.fireWith(g,[E,C]),f&&(y.trigger("ajaxComplete",[E,h]),--w.active||w.event.trigger("ajaxStop")))}return E},getJSON:function(e,t,n){return w.get(e,t,n,"json")},getScript:function(e,t){return w.get(e,void 0,t,"script")}}),w.each(["get","post"],function(e,t){w[t]=function(e,n,r,i){return g(n)&&(i=i||r,r=n,n=void 0),w.ajax(w.extend({url:e,type:t,dataType:i,data:n,success:r},w.isPlainObject(e)&&e))}}),w._evalUrl=function(e){return w.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},w.fn.extend({wrapAll:function(e){var t;return this[0]&&(g(e)&&(e=e.call(this[0])),t=w(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return g(e)?this.each(function(t){w(this).wrapInner(e.call(this,t))}):this.each(function(){var t=w(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=g(e);return this.each(function(n){w(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not("body").each(function(){w(this).replaceWith(this.childNodes)}),this}}),w.expr.pseudos.hidden=function(e){return!w.expr.pseudos.visible(e)},w.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},w.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var Vt={0:200,1223:204},Gt=w.ajaxSettings.xhr();h.cors=!!Gt&&"withCredentials"in Gt,h.ajax=Gt=!!Gt,w.ajaxTransport(function(t){var n,r;if(h.cors||Gt&&!t.crossDomain)return{send:function(i,o){var a,s=t.xhr();if(s.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(a in t.xhrFields)s[a]=t.xhrFields[a];t.mimeType&&s.overrideMimeType&&s.overrideMimeType(t.mimeType),t.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");for(a in i)s.setRequestHeader(a,i[a]);n=function(e){return function(){n&&(n=r=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===e?s.abort():"error"===e?"number"!=typeof s.status?o(0,"error"):o(s.status,s.statusText):o(Vt[s.status]||s.status,s.statusText,"text"!==(s.responseType||"text")||"string"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=n(),r=s.onerror=s.ontimeout=n("error"),void 0!==s.onabort?s.onabort=r:s.onreadystatechange=function(){4===s.readyState&&e.setTimeout(function(){n&&r()})},n=n("abort");try{s.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),w.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),w.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return w.globalEval(e),e}}}),w.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),w.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(i,o){t=w("<script>").prop({charset:e.scriptCharset,src:e.url}).on("load error",n=function(e){t.remove(),n=null,e&&o("error"===e.type?404:200,e.type)}),r.head.appendChild(t[0])},abort:function(){n&&n()}}}});var Yt=[],Qt=/(=)\?(?=&|$)|\?\?/;w.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Yt.pop()||w.expando+"_"+Et++;return this[e]=!0,e}}),w.ajaxPrefilter("json jsonp",function(t,n,r){var i,o,a,s=!1!==t.jsonp&&(Qt.test(t.url)?"url":"string"==typeof t.data&&0===(t.contentType||"").indexOf("application/x-www-form-urlencoded")&&Qt.test(t.data)&&"data");if(s||"jsonp"===t.dataTypes[0])return i=t.jsonpCallback=g(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,s?t[s]=t[s].replace(Qt,"$1"+i):!1!==t.jsonp&&(t.url+=(kt.test(t.url)?"&":"?")+t.jsonp+"="+i),t.converters["script json"]=function(){return a||w.error(i+" was not called"),a[0]},t.dataTypes[0]="json",o=e[i],e[i]=function(){a=arguments},r.always(function(){void 0===o?w(e).removeProp(i):e[i]=o,t[i]&&(t.jsonpCallback=n.jsonpCallback,Yt.push(i)),a&&g(o)&&o(a[0]),a=o=void 0}),"script"}),h.createHTMLDocument=function(){var e=r.implementation.createHTMLDocument("").body;return e.innerHTML="<form></form><form></form>",2===e.childNodes.length}(),w.parseHTML=function(e,t,n){if("string"!=typeof e)return[];"boolean"==typeof t&&(n=t,t=!1);var i,o,a;return t||(h.createHTMLDocument?((i=(t=r.implementation.createHTMLDocument("")).createElement("base")).href=r.location.href,t.head.appendChild(i)):t=r),o=A.exec(e),a=!n&&[],o?[t.createElement(o[1])]:(o=xe([e],t,a),a&&a.length&&w(a).remove(),w.merge([],o.childNodes))},w.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return s>-1&&(r=vt(e.slice(s)),e=e.slice(0,s)),g(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),a.length>0&&w.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?w("<div>").append(w.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},w.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){w.fn[t]=function(e){return this.on(t,e)}}),w.expr.pseudos.animated=function(e){return w.grep(w.timers,function(t){return e===t.elem}).length},w.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l,c=w.css(e,"position"),f=w(e),p={};"static"===c&&(e.style.position="relative"),s=f.offset(),o=w.css(e,"top"),u=w.css(e,"left"),(l=("absolute"===c||"fixed"===c)&&(o+u).indexOf("auto")>-1)?(a=(r=f.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),g(t)&&(t=t.call(e,n,w.extend({},s))),null!=t.top&&(p.top=t.top-s.top+a),null!=t.left&&(p.left=t.left-s.left+i),"using"in t?t.using.call(e,p):f.css(p)}},w.fn.extend({offset:function(e){if(arguments.length)return void 0===e?this:this.each(function(t){w.offset.setOffset(this,e,t)});var t,n,r=this[0];if(r)return r.getClientRects().length?(t=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:t.top+n.pageYOffset,left:t.left+n.pageXOffset}):{top:0,left:0}},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===w.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===w.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=w(e).offset()).top+=w.css(e,"borderTopWidth",!0),i.left+=w.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-w.css(r,"marginTop",!0),left:t.left-i.left-w.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===w.css(e,"position"))e=e.offsetParent;return e||be})}}),w.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,t){var n="pageYOffset"===t;w.fn[e]=function(r){return z(this,function(e,r,i){var o;if(y(e)?o=e:9===e.nodeType&&(o=e.defaultView),void 0===i)return o?o[t]:e[r];o?o.scrollTo(n?o.pageXOffset:i,n?i:o.pageYOffset):e[r]=i},e,r,arguments.length)}}),w.each(["top","left"],function(e,t){w.cssHooks[t]=_e(h.pixelPosition,function(e,n){if(n)return n=Fe(e,t),We.test(n)?w(e).position()[t]+"px":n})}),w.each({Height:"height",Width:"width"},function(e,t){w.each({padding:"inner"+e,content:t,"":"outer"+e},function(n,r){w.fn[r]=function(i,o){var a=arguments.length&&(n||"boolean"!=typeof i),s=n||(!0===i||!0===o?"margin":"border");return z(this,function(t,n,i){var o;return y(t)?0===r.indexOf("outer")?t["inner"+e]:t.document.documentElement["client"+e]:9===t.nodeType?(o=t.documentElement,Math.max(t.body["scroll"+e],o["scroll"+e],t.body["offset"+e],o["offset"+e],o["client"+e])):void 0===i?w.css(t,n,s):w.style(t,n,i,s)},t,a?i:void 0,a)}})}),w.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,t){w.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),w.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),w.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}}),w.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),g(e))return r=o.call(arguments,2),i=function(){return e.apply(t||this,r.concat(o.call(arguments)))},i.guid=e.guid=e.guid||w.guid++,i},w.holdReady=function(e){e?w.readyWait++:w.ready(!0)},w.isArray=Array.isArray,w.parseJSON=JSON.parse,w.nodeName=N,w.isFunction=g,w.isWindow=y,w.camelCase=G,w.type=x,w.now=Date.now,w.isNumeric=function(e){var t=w.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},"function"==typeof define&&define.amd&&define("jquery",[],function(){return w});var Jt=e.jQuery,Kt=e.$;return w.noConflict=function(t){return e.$===w&&(e.$=Kt),t&&e.jQuery===w&&(e.jQuery=Jt),w},t||(e.jQuery=e.$=w),w});
3 4 5 6; 7////pf: javascript/jquery-migrate-3.0.1.js 8/*! jQuery Migrate v3.0.1 | (c) jQuery Foundation and other contributors | jquery.org/license */ 9 10void 0 === jQuery.migrateMute && (jQuery.migrateMute = !0), function(e) { 11 "function" == typeof define && define.amd ? define([ "jquery" ], window, e) : "object" == typeof module && module.exports ? module.exports = e(require("jquery"), window) : e(jQuery, window); 12}(function(e, t) { 13 "use strict"; 14 function r(r) { 15 var n = t.console; 16 o[r] || (o[r] = !0, e.migrateWarnings.push(r), n && n.warn && !e.migrateMute && (n.warn("JQMIGRATE: " + r), 17 e.migrateTrace && n.trace && n.trace())); 18 } 19 function n(e, t, n, a) { 20 Object.defineProperty(e, t, { 21 configurable: !0, 22 enumerable: !0, 23 get: function() { 24 return r(a), n; 25 }, 26 set: function(e) { 27 r(a), n = e; 28 } 29 }); 30 } 31 function a(e, t, n, a) { 32 e[t] = function() { 33 return r(a), n.apply(this, arguments); 34 }; 35 } 36 e.migrateVersion = "3.0.1", function() { 37 var r = /^[12]\./; 38 t.console && t.console.log && (e && !r.test(e.fn.jquery) || t.console.log("JQMIGRATE: jQuery 3.0.0+ REQUIRED"), 39 e.migrateWarnings && t.console.log("JQMIGRATE: Migrate plugin loaded multiple times"), 40 t.console.log("JQMIGRATE: Migrate is installed" + (e.migrateMute ? "" : " with logging active") + ", version " + e.migrateVersion)); 41 }(); 42 var o = {}; 43 e.migrateWarnings = [], void 0 === e.migrateTrace && (e.migrateTrace = !0), e.migrateReset = function() { 44 o = {}, e.migrateWarnings.length = 0; 45 }, "BackCompat" === t.document.compatMode && r("jQuery is not compatible with Quirks Mode"); 46 var i = e.fn.init, s = e.isNumeric, u = e.find, c = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/, l = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g; 47 e.fn.init = function(e) { 48 var t = Array.prototype.slice.call(arguments); 49 return "string" == typeof e && "#" === e && (r("jQuery( '#' ) is not a valid selector"), 50 t[0] = []), i.apply(this, t); 51 }, e.fn.init.prototype = e.fn, e.find = function(e) { 52 var n = Array.prototype.slice.call(arguments); 53 if ("string" == typeof e && c.test(e)) try { 54 t.document.querySelector(e); 55 } catch (a) { 56 e = e.replace(l, function(e, t, r, n) { 57 return "[" + t + r + '"' + n + '"]'; 58 }); 59 try { 60 t.document.querySelector(e), r("Attribute selector with '#' must be quoted: " + n[0]), 61 n[0] = e; 62 } catch (e) { 63 r("Attribute selector with '#' was not fixed: " + n[0]); 64 } 65 } 66 return u.apply(this, n); 67 }; 68 var d; 69 for (d in u) Object.prototype.hasOwnProperty.call(u, d) && (e.find[d] = u[d]); 70 e.fn.size = function() { 71 return r("jQuery.fn.size() is deprecated and removed; use the .length property"), 72 this.length; 73 }, e.parseJSON = function() { 74 return r("jQuery.parseJSON is deprecated; use JSON.parse"), JSON.parse.apply(null, arguments); 75 }, e.isNumeric = function(t) { 76 var n = s(t), a = function(t) { 77 var r = t && t.toString(); 78 return !e.isArray(t) && r - parseFloat(r) + 1 >= 0; 79 }(t); 80 return n !== a && r("jQuery.isNumeric() should not be called on constructed objects"), 81 a; 82 }, a(e, "holdReady", e.holdReady, "jQuery.holdReady is deprecated"), a(e, "unique", e.uniqueSort, "jQuery.unique is deprecated; use jQuery.uniqueSort"), 83 n(e.expr, "filters", e.expr.pseudos, "jQuery.expr.filters is deprecated; use jQuery.expr.pseudos"), 84 n(e.expr, ":", e.expr.pseudos, "jQuery.expr[':'] is deprecated; use jQuery.expr.pseudos"); 85 var p = e.ajax; 86 e.ajax = function() { 87 var e = p.apply(this, arguments); 88 return e.promise && (a(e, "success", e.done, "jQXHR.success is deprecated and removed"), 89 a(e, "error", e.fail, "jQXHR.error is deprecated and removed"), a(e, "complete", e.always, "jQXHR.complete is deprecated and removed")), 90 e; 91 }; 92 var f = e.fn.removeAttr, y = e.fn.toggleClass, m = /\S+/g; 93 e.fn.removeAttr = function(t) { 94 var n = this; 95 return e.each(t.match(m), function(t, a) { 96 e.expr.match.bool.test(a) && (r("jQuery.fn.removeAttr no longer sets boolean properties: " + a), 97 n.prop(a, !1)); 98 }), f.apply(this, arguments); 99 }, e.fn.toggleClass = function(t) { 100 return void 0 !== t && "boolean" != typeof t ? y.apply(this, arguments) : (r("jQuery.fn.toggleClass( boolean ) is deprecated"), 101 this.each(function() { 102 var r = this.getAttribute && this.getAttribute("class") || ""; 103 r && e.data(this, "__className__", r), this.setAttribute && this.setAttribute("class", r || !1 === t ? "" : e.data(this, "__className__") || ""); 104 })); 105 }; 106 var h = !1; 107 e.swap && e.each([ "height", "width", "reliableMarginRight" ], function(t, r) { 108 var n = e.cssHooks[r] && e.cssHooks[r].get; 109 n && (e.cssHooks[r].get = function() { 110 var e; 111 return h = !0, e = n.apply(this, arguments), h = !1, e; 112 }); 113 }), e.swap = function(e, t, n, a) { 114 var o, i, s = {}; 115 h || r("jQuery.swap() is undocumented and deprecated"); 116 for (i in t) s[i] = e.style[i], e.style[i] = t[i]; 117 o = n.apply(e, a || []); 118 for (i in t) e.style[i] = s[i];
119 return o; 120 }; 121 var g = e.data; 122 e.data = function(t, n, a) { 123 var o; 124 if (n && "object" == typeof n && 2 === arguments.length) { 125 o = e.hasData(t) && g.call(this, t); 126 var i = {}; 127 for (var s in n) s !== e.camelCase(s) ? (r("jQuery.data() always sets/gets camelCased names: " + s), 128 o[s] = n[s]) : i[s] = n[s]; 129 return g.call(this, t, i), n; 130 } 131 return n && "string" == typeof n && n !== e.camelCase(n) && (o = e.hasData(t) && g.call(this, t)) && n in o ? (r("jQuery.data() always sets/gets camelCased names: " + n), 132 arguments.length > 2 && (o[n] = a), o[n]) : g.apply(this, arguments); 133 }; 134 var v = e.Tween.prototype.run, j = function(e) { 135 return e; 136 }; 137 e.Tween.prototype.run = function() { 138 e.easing[this.easing].length > 1 && (r("'jQuery.easing." + this.easing.toString() + "' should use only one argument"), 139 e.easing[this.easing] = j), v.apply(this, arguments); 140 }, e.fx.interval = e.fx.interval || 13, t.requestAnimationFrame && n(e.fx, "interval", e.fx.interval, "jQuery.fx.interval is deprecated"); 141 var Q = e.fn.load, b = e.event.add, w = e.event.fix; 142 e.event.props = [], e.event.fixHooks = {}, n(e.event.props, "concat", e.event.props.concat, "jQuery.event.props.concat() is deprecated and removed"), 143 e.event.fix = function(t) { 144 var n, a = t.type, o = this.fixHooks[a], i = e.event.props; 145 if (i.length) for (r("jQuery.event.props are deprecated and removed: " + i.join()); i.length; ) e.event.addProp(i.pop()); 146 if (o && !o._migrated_ && (o._migrated_ = !0, r("jQuery.event.fixHooks are deprecated and removed: " + a), 147 (i = o.props) && i.length)) for (;i.length; ) e.event.addProp(i.pop()); 148 return n = w.call(this, t), o && o.filter ? o.filter(n, t) : n; 149 }, e.event.add = function(e, n) { 150 return e === t && "load" === n && "complete" === t.document.readyState && r("jQuery(window).on('load'...) called after load event occurred"), 151 b.apply(this, arguments); 152 }, e.each([ "load", "unload", "error" ], function(t, n) { 153 e.fn[n] = function() { 154 var e = Array.prototype.slice.call(arguments, 0); 155 return "load" === n && "string" == typeof e[0] ? Q.apply(this, e) : (r("jQuery.fn." + n + "() is deprecated"), 156 e.splice(0, 0, n), arguments.length ? this.on.apply(this, e) : (this.triggerHandler.apply(this, e), 157 this)); 158 }; 159 }), e.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "), function(t, n) { 160 e.fn[n] = function(e, t) { 161 return r("jQuery.fn." + n + "() event shorthand is deprecated"), arguments.length > 0 ? this.on(n, null, e, t) : this.trigger(n); 162 }; 163 }), e(function() { 164 e(t.document).triggerHandler("ready"); 165 }), e.event.special.ready = { 166 setup: function() { 167 this === t.document && r("'ready' event is deprecated"); 168 } 169 }, e.fn.extend({ 170 bind: function(e, t, n) { 171 return r("jQuery.fn.bind() is deprecated"), this.on(e, null, t, n); 172 }, 173 unbind: function(e, t) { 174 return r("jQuery.fn.unbind() is deprecated"), this.off(e, null, t); 175 }, 176 delegate: function(e, t, n, a) { 177 return r("jQuery.fn.delegate() is deprecated"), this.on(t, e, n, a); 178 }, 179 undelegate: function(e, t, n) { 180 return r("jQuery.fn.undelegate() is deprecated"), 1 === arguments.length ? this.off(e, "**") : this.off(t, e || "**", n); 181 }, 182 hover: function(e, t) { 183 return r("jQuery.fn.hover() is deprecated"), this.on("mouseenter", e).on("mouseleave", t || e); 184 } 185 }); 186 var x = e.fn.offset; 187 e.fn.offset = function() { 188 var n, a = this[0], o = { 189 top: 0, 190 left: 0 191 }; 192 return a && a.nodeType ? (n = (a.ownerDocument || t.document).documentElement, e.contains(n, a) ? x.apply(this, arguments) : (r("jQuery.fn.offset() requires an element connected to a document"), 193 o)) : (r("jQuery.fn.offset() requires a valid DOM element"), o); 194 }; 195 var k = e.param; 196 e.param = function(t, n) { 197 var a = e.ajaxSettings && e.ajaxSettings.traditional; 198 return void 0 === n && a && (r("jQuery.param() no longer uses jQuery.ajaxSettings.traditional"), 199 n = a), k.call(this, t, n); 200 }; 201 var A = e.fn.andSelf || e.fn.addBack; 202 e.fn.andSelf = function() { 203 return r("jQuery.fn.andSelf() is deprecated and removed, use jQuery.fn.addBack()"), 204 A.apply(this, arguments); 205 }; 206 var S = e.Deferred, q = [ [ "resolve", "done", e.Callbacks("once memory"), e.Callbacks("once memory"), "resolved" ], [ "reject", "fail", e.Callbacks("once memory"), e.Callbacks("once memory"), "rejected" ], [ "notify", "progress", e.Callbacks("memory"), e.Callbacks("memory") ] ]; 207 return e.Deferred = function(t) { 208 var n = S(), a = n.promise(); 209 return n.pipe = a.pipe = function() { 210 var t = arguments; 211 return r("deferred.pipe() is deprecated"), e.Deferred(function(r) { 212 e.each(q, function(o, i) { 213 var s = e.isFunction(t[o]) && t[o]; 214 n[i[1]](function() { 215 var t = s && s.apply(this, arguments); 216 t && e.isFunction(t.promise) ? t.promise().done(r.resolve).fail(r.reject).progress(r.notify) : r[i[0] + "With"](this === a ? r.promise() : this, s ? [ t ] : arguments); 217 }); 218 }), t = null; 219 }).promise(); 220 }, t && t.call(n, n), n; 221 }, e.Deferred.exceptionHook = S.exceptionHook, e; 222}); 223 224; 225////pf: javascript/jquery.waypoints.min.js 226/*! 227Waypoints - 4.0.0 228Copyright © 2011-2015 Caleb Troughton 229Licensed under the MIT license. 230https://github.com/imakewebthings/waypoints/blog/master/licenses.txt 231*/ 232!function(){"use strict";function t(o){if(!o)throw new Error("No options passed to Waypoint constructor");if(!o.element)throw new Error("No element option passed to Waypoint constructor");if(!o.handler)throw new Error("No handler option passed to Waypoint constructor");
vendor: 6,536 bytes, line 232
232this.key="waypoint-"+e,this.options=t.Adapter.extend({},t.defaults,o),this.element=this.options.element,this.adapter=new t.Adapter(this.element),this.callback=o.handler,this.axis=this.options.horizontal?"horizontal":"vertical",this.enabled=this.options.enabled,this.triggerPoint=null,this.group=t.Group.findOrCreate({name:this.options.group,axis:this.axis}),this.context=t.Context.findOrCreateByElement(this.options.context),t.offsetAliases[this.options.offset]&&(this.options.offset=t.offsetAliases[this.options.offset]),this.group.add(this),this.context.add(this),i[this.key]=this,e+=1}var e=0,i={};t.prototype.queueTrigger=function(t){this.group.queueTrigger(this,t)},t.prototype.trigger=function(t){this.enabled&&this.callback&&this.callback.apply(this,t)},t.prototype.destroy=function(){this.context.remove(this),this.group.remove(this),delete i[this.key]},t.prototype.disable=function(){return this.enabled=!1,this},t.prototype.enable=function(){return this.context.refresh(),this.enabled=!0,this},t.prototype.next=function(){return this.group.next(this)},t.prototype.previous=function(){return this.group.previous(this)},t.invokeAll=function(t){var e=[];for(var o in i)e.push(i[o]);for(var n=0,r=e.length;r>n;n++)e[n][t]()},t.destroyAll=function(){t.invokeAll("destroy")},t.disableAll=function(){t.invokeAll("disable")},t.enableAll=function(){t.invokeAll("enable")},t.refreshAll=function(){t.Context.refreshAll()},t.viewportHeight=function(){return window.innerHeight||document.documentElement.clientHeight},t.viewportWidth=function(){return document.documentElement.clientWidth},t.adapters=[],t.defaults={context:window,continuous:!0,enabled:!0,group:"default",horizontal:!1,offset:0},t.offsetAliases={"bottom-in-view":function(){return this.context.innerHeight()-this.adapter.outerHeight(false)},"right-in-view":function(){return this.context.innerWidth()-this.adapter.outerWidth(false)}},window.Waypoint=t}(),function(){"use strict";function t(t){window.setTimeout(t,1e3/60)}function e(t){this.element=t,this.Adapter=n.Adapter,this.adapter=new this.Adapter(t),this.key="waypoint-context-"+i,this.didScroll=!1,this.didResize=!1,this.oldScroll={x:this.adapter.scrollLeft(),y:this.adapter.scrollTop()},this.waypoints={vertical:{},horizontal:{}},t.waypointContextKey=this.key,o[t.waypointContextKey]=this,i+=1,this.createThrottledScrollHandler(),this.createThrottledResizeHandler()}var i=0,o={},n=window.Waypoint,r=window.onload;e.prototype.add=function(t){var e=t.options.horizontal?"horizontal":"vertical";this.waypoints[e][t.key]=t,this.refresh()},e.prototype.checkEmpty=function(){var t=this.Adapter.isEmptyObject(this.waypoints.horizontal),e=this.Adapter.isEmptyObject(this.waypoints.vertical);t&&e&&(this.adapter.off(".waypoints"),delete o[this.key])},e.prototype.createThrottledResizeHandler=function(){function t(){e.handleResize(),e.didResize=!1}var e=this;this.adapter.on("resize.waypoints",function(){e.didResize||(e.didResize=!0,n.requestAnimationFrame(t))})},e.prototype.createThrottledScrollHandler=function(){function t(){e.handleScroll(),e.didScroll=!1}var e=this;this.adapter.on("scroll.waypoints",function(){(!e.didScroll||n.isTouch)&&(e.didScroll=!0,n.requestAnimationFrame(t))})},e.prototype.handleResize=function(){n.Context.refreshAll()},e.prototype.handleScroll=function(){var t={},e={horizontal:{newScroll:this.adapter.scrollLeft(),oldScroll:this.oldScroll.x,forward:"right",backward:"left"},vertical:{newScroll:this.adapter.scrollTop(),oldScroll:this.oldScroll.y,forward:"down",backward:"up"}};for(var i in e){var o=e[i],n=o.newScroll>o.oldScroll,r=n?o.forward:o.backward;for(var s in this.waypoints[i]){var a=this.waypoints[i][s],l=o.oldScroll<a.triggerPoint,h=o.newScroll>=a.triggerPoint,p=l&&h,u=!l&&!h;(p||u)&&(a.queueTrigger(r),t[a.group.id]=a.group)}}for(var c in t)t[c].flushTriggers();this.oldScroll={x:e.horizontal.newScroll,y:e.vertical.newScroll}},e.prototype.innerHeight=function(){return this.element==this.element.window?n.viewportHeight():this.adapter.innerHeight()},e.prototype.remove=function(t){delete this.waypoints[t.axis][t.key],this.checkEmpty()},e.prototype.innerWidth=function(){return this.element==this.element.window?n.viewportWidth():this.adapter.innerWidth()},e.prototype.destroy=function(){var t=[];for(var e in this.waypoints)for(var i in this.waypoints[e])t.push(this.waypoints[e][i]);for(var o=0,n=t.length;n>o;o++)t[o].destroy()},e.prototype.refresh=function(){var t,e=this.element==this.element.window,i=e?void 0:this.adapter.offset(),o={};this.handleScroll(),t={horizontal:{contextOffset:e?0:i.left,contextScroll:e?0:this.oldScroll.x,contextDimension:this.innerWidth(),oldScroll:this.oldScroll.x,forward:"right",backward:"left",offsetProp:"left"},vertical:{contextOffset:e?0:i.top,contextScroll:e?0:this.oldScroll.y,contextDimension:this.innerHeight(),oldScroll:this.oldScroll.y,forward:"down",backward:"up",offsetProp:"top"}};for(var r in t){var s=t[r];for(var a in this.waypoints[r]){var l,h,p,u,c,d=this.waypoints[r][a],f=d.options.offset,w=d.triggerPoint,y=0,g=null==w;d.element!==d.element.window&&(y=d.adapter.offset()[s.offsetProp]),"function"==typeof f?f=f.apply(d):"string"==typeof f&&(f=parseFloat(f),d.options.offset.indexOf("%")>-1&&(f=Math.ceil(s.contextDimension*f/100))),l=s.contextScroll-s.contextOffset,d.triggerPoint=y+l-f,h=w<s.oldScroll,p=d.triggerPoint>=s.oldScroll,u=h&&p,c=!h&&!p,!g&&u?(d.queueTrigger(s.backward),o[d.group.id]=d.group):!g&&c?(d.queueTrigger(s.forward),o[d.group.id]=d.group):g&&s.oldScroll>=d.triggerPoint&&(d.queueTrigger(s.forward),o[d.group.id]=d.group)}}return n.requestAnimationFrame(function(){for(var t in o)o[t].flushTriggers()}),this},e.findOrCreateByElement=function(t){return e.findByElement(t)||new e(t)},e.refreshAll=function(){for(var t in o)o[t].refresh()},e.findByElement=function(t){return o[t.waypointContextKey]},window.onload=function(){r&&r(),e.refreshAll()},n.requestAnimationFrame=function(e){var i=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||t;i.call(window,e)},n.Context=e}(),function(){"use strict";function t(t,e){return t.triggerPoint-e.triggerPoint}function e(t,e){return e.triggerPoint-t.triggerPoint}function i(t){this.name=t.name,this.axis=t.axis,this.id=this.name+"-"+this.axis,this.waypoints=[],this.clearTriggerQueues(),o[this.axis][this.name]=this}var o={vertical:{},horizontal:{}},n=window.Waypoint;i.prototype.add=function(t){this.waypoints.push(t)},i.prototype.clearTriggerQueues=function(){this.triggerQueues={up:[],down:[],left:[],r
232ight:[]}},i.prototype.flushTriggers=function(){for(var i in this.triggerQueues){var o=this.triggerQueues[i],n="up"===i||"left"===i;o.sort(n?e:t);for(var r=0,s=o.length;s>r;r+=1){var a=o[r];(a.options.continuous||r===o.length-1)&&a.trigger([i])}}this.clearTriggerQueues()},i.prototype.next=function(e){this.waypoints.sort(t);var i=n.Adapter.inArray(e,this.waypoints),o=i===this.waypoints.length-1;return o?null:this.waypoints[i+1]},i.prototype.previous=function(e){this.waypoints.sort(t);var i=n.Adapter.inArray(e,this.waypoints);return i?this.waypoints[i-1]:null},i.prototype.queueTrigger=function(t,e){this.triggerQueues[e].push(t)},i.prototype.remove=function(t){var e=n.Adapter.inArray(t,this.waypoints);e>-1&&this.waypoints.splice(e,1)},i.prototype.first=function(){return this.waypoints[0]},i.prototype.last=function(){return this.waypoints[this.waypoints.length-1]},i.findOrCreate=function(t){return o[t.axis][t.name]||new i(t)},n.Group=i}(),function(){"use strict";function t(t){this.$element=e(t)}var e=window.jQuery,i=window.Waypoint;e.each(["innerHeight","innerWidth","off","offset","on","outerHeight","outerWidth","scrollLeft","scrollTop"],function(e,i){t.prototype[i]=function(){var t=Array.prototype.slice.call(arguments);return this.$element[i].apply(this.$element,t)}}),e.each(["extend","inArray","isEmptyObject"],function(i,o){t[o]=e[o]}),i.adapters.push({name:"jquery",Adapter:t}),i.Adapter=t}(),function(){"use strict";function t(t){return function(){var i=[],o=arguments[0];return t.isFunction(arguments[0])&&(o=t.extend({},arguments[1]),o.handler=arguments[0]),this.each(function(){var n=t.extend({},o,{element:this});"string"==typeof n.context&&(n.context=t(this).closest(n.context)[0]),i.push(new e(n))}),i}}var e=window.Waypoint;window.jQuery&&(window.jQuery.fn.waypoint=t(window.jQuery)),window.Zepto&&(window.Zepto.fn.waypoint=t(window.Zepto))}(); 233 234 235; 236////pf: javascript/jquery.color-2.1.2.min.js 237/*! jQuery Color [email protected] http://github.com/jquery/jquery-color | jquery.org/license */ 238(function(a,b){function m(a,b,c){var d=h[b.type]||{};return a==null?c||!b.def?null:b.def:(a=d.floor?~~a:parseFloat(a),isNaN(a)?b.def:d.mod?(a+d.mod)%d.mod:0>a?0:d.max<a?d.max:a)}function n(b){var c=f(),d=c._rgba=[];return b=b.toLowerCase(),l(e,function(a,e){var f,h=e.re.exec(b),i=h&&e.parse(h),j=e.space||"rgba";if(i)return f=c[j](i),c[g[j].cache]=f[g[j].cache],d=c._rgba=f._rgba,!1}),d.length?(d.join()==="0,0,0,0"&&a.extend(d,k.transparent),c):k[b]}function o(a,b,c){return c=(c+1)%1,c*6<1?a+(b-a)*c*6:c*2<1?b:c*3<2?a+(b-a)*(2/3-c)*6:a}var c="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",d=/^([\-+])=\s*(\d+\.?\d*)/,e=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(a){return[a[1],a[2],a[3],a[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(a){return[a[1]*2.55,a[2]*2.55,a[3]*2.55,a[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(a){return[parseInt(a[1],16),parseInt(a[2],16),parseInt(a[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(a){return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(a){return[a[1],a[2]/100,a[3]/100,a[4]]}}],f=a.Color=function(b,c,d,e){return new a.Color.fn.parse(b,c,d,e)},g={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},h={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},i=f.support={},j=a("<p>")[0],k,l=a.each;j.style.cssText="background-color:rgba(1,1,1,.5)",i.rgba=j.style.backgroundColor.indexOf("rgba")>-1,l(g,function(a,b){b.cache="_"+a,b.props.alpha={idx:3,type:"percent",def:1}}),f.fn=a.extend(f.prototype,{parse:function(c,d,e,h){if(c===b)return this._rgba=[null,null,null,null],this;if(c.jquery||c.nodeType)c=a(c).css(d),d=b;var i=this,j=a.type(c),o=this._rgba=[];d!==b&&(c=[c,d,e,h],j="array");if(j==="string")return this.parse(n(c)||k._default);if(j==="array")return l(g.rgba.props,function(a,b){o[b.idx]=m(c[b.idx],b)}),this;
238if(j==="object")return c instanceof f?l(g,function(a,b){c[b.cache]&&(i[b.cache]=c[b.cache].slice())}):l(g,function(b,d){var e=d.cache;l(d.props,function(a,b){if(!i[e]&&d.to){if(a==="alpha"||c[a]==null)return;i[e]=d.to(i._rgba)}i[e][b.idx]=m(c[a],b,!0)}),i[e]&&a.inArray(null,i[e].slice(0,3))<0&&(i[e][3]=1,d.from&&(i._rgba=d.from(i[e])))}),this},is:function(a){var b=f(a),c=!0,d=this;return l(g,function(a,e){var f,g=b[e.cache];return g&&(f=d[e.cache]||e.to&&e.to(d._rgba)||[],l(e.props,function(a,b){if(g[b.idx]!=null)return c=g[b.idx]===f[b.idx],c})),c}),c},_space:function(){var a=[],b=this;return l(g,function(c,d){b[d.cache]&&a.push(c)}),a.pop()},transition:function(a,b){var c=f(a),d=c._space(),e=g[d],i=this.alpha()===0?f("transparent"):this,j=i[e.cache]||e.to(i._rgba),k=j.slice();return c=c[e.cache],l(e.props,function(a,d){var e=d.idx,f=j[e],g=c[e],i=h[d.type]||{};if(g===null)return;f===null?k[e]=g:(i.mod&&(g-f>i.mod/2?f+=i.mod:f-g>i.mod/2&&(f-=i.mod)),k[e]=m((g-f)*b+f,d))}),this[d](k)},blend:function(b){if(this._rgba[3]===1)return this;var c=this._rgba.slice(),d=c.pop(),e=f(b)._rgba;return f(a.map(c,function(a,b){return(1-d)*e[b]+d*a}))},toRgbaString:function(){var b="rgba(",c=a.map(this._rgba,function(a,b){return a==null?b>2?1:0:a});return c[3]===1&&(c.pop(),b="rgb("),b+c.join()+")"},toHslaString:function(){var b="hsla(",c=a.map(this.hsla(),function(a,b){return a==null&&(a=b>2?1:0),b&&b<3&&(a=Math.round(a*100)+"%"),a});return c[3]===1&&(c.pop(),b="hsl("),b+c.join()+")"},toHexString:function(b){var c=this._rgba.slice(),d=c.pop();return b&&c.push(~~(d*255)),"#"+a.map(c,function(a){return a=(a||0).toString(16),a.length===1?"0"+a:a}).join("")},toString:function(){return this._rgba[3]===0?"transparent":this.toRgbaString()}}),f.fn.parse.prototype=f.fn,g.hsla.to=function(a){if(a[0]==null||a[1]==null||a[2]==null)return[null,null,null,a[3]];var b=a[0]/255,c=a[1]/255,d=a[2]/255,e=a[3],f=Math.max(b,c,d),g=Math.min(b,c,d),h=f-g,i=f+g,j=i*.5,k,l;return g===f?k=0:b===f?k=60*(c-d)/h+360:c===f?k=60*(d-b)/h+120:k=60*(b-c)/h+240,h===0?l=0:j<=.5?l=h/i:l=h/(2-i),[Math.round(k)%360,l,j,e==null?1:e]},g.hsla.from=function(a){if(a[0]==null||a[1]==null||a[2]==null)return[null,null,null,a[3]];var b=a[0]/360,c=a[1],d=a[2],e=a[3],f=d<=.5?d*(1+c):d+c-d*c,g=2*d-f;return[Math.round(o(g,f,b+1/3)*255),Math.round(o(g,f,b)*255),Math.round(o(g,f,b-1/3)*255),e]},l(g,function(c,e){var g=e.props,h=e.cache,i=e.to,j=e.from;f.fn[c]=function(c){i&&!this[h]&&(this[h]=i(this._rgba));if(c===b)return this[h].slice();var d,e=a.type(c),k=e==="array"||e==="object"?c:arguments,n=this[h].slice();return l(g,function(a,b){var c=k[e==="object"?a:b.idx];c==null&&(c=n[b.idx]),n[b.idx]=m(c,b)}),j?(d=f(j(n)),d[h]=n,d):f(n)},l(g,function(b,e){if(f.fn[b])return;f.fn[b]=function(f){var g=a.type(f),h=b==="alpha"?this._hsla?"hsla":"rgba":c,i=this[h](),j=i[e.idx],k;return g==="undefined"?j:(g==="function"&&(f=f.call(this,j),g=a.type(f)),f==null&&e.empty?this:(g==="string"&&(k=d.exec(f),k&&(f=j+parseFloat(k[2])*(k[1]==="+"?1:-1))),i[e.idx]=f,this[h](i)))}})}),f.hook=function(b){var c=b.split(" ");l(c,function(b,c){a.cssHooks[c]={set:function(b,d){var e,g,h="";if(d!=="transparent"&&(a.type(d)!=="string"||(e=n(d)))){d=f(e||d);if(!i.rgba&&d._rgba[3]!==1){g=c==="backgroundColor"?b.parentNode:b;while((h===""||h==="transparent")&&g&&g.style)try{h=a.css(g,"backgroundColor"),g=g.parentNode}catch(j){}d=d.blend(h&&h!=="transparent"?h:"_default")}d=d.toRgbaString()}try{b.style[c]=d}catch(j){}}},a.fx.step[c]=function(b){b.colorInit||(b.start=f(b.elem,c),b.end=f(b.end),b.colorInit=!0),a.cssHooks[c].set(b.elem,b.start.transition(b.end,b.pos))}})},f.hook(c),a.cssHooks.borderColor={expand:function(a){var b={};return l(["Top","Right","Bottom","Left"],function(c,d){b["border"+d+"Color"]=a}),b}},k=a.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}})(jQuery); 239 240; 241////pf: javascript/jquery.validate.min.js 242/** 243 * jQuery Validation Plugin 1.8.1 244 * 245 * http://bassistance.de/jquery-plugins/jquery-plugin-validation/ 246 * http://docs.jquery.com/Plugins/Validation 247 * 248 * Copyright (c) 2006 - 2011 Jörn Zaefferer 249 * 250 * Dual licensed under the MIT and GPL licenses: 251 * http://www.opensource.org/licenses/mit-license.php 252 * http://www.gnu.org/licenses/gpl.html 253 */
254(function(c){c.extend(c.fn,{validate:function(a){if(this.length){var b=c.data(this[0],"validator");if(b)return b;b=new c.validator(a,this[0]);c.data(this[0],"validator",b);if(b.settings.onsubmit){this.find("input, button").filter(".cancel").click(function(){b.cancelSubmit=true});b.settings.submitHandler&&this.find("input, button").filter(":submit").click(function(){b.submitButton=this});this.submit(function(d){function e(){if(b.settings.submitHandler){if(b.submitButton)var f=c("<input type='hidden'/>").attr("name", 255b.submitButton.name).val(b.submitButton.value).appendTo(b.currentForm);b.settings.submitHandler.call(b,b.currentForm);b.submitButton&&f.remove();return false}return true}b.settings.debug&&d.preventDefault();if(b.cancelSubmit){b.cancelSubmit=false;return e()}if(b.form()){if(b.pendingRequest){b.formSubmitted=true;return false}return e()}else{b.focusInvalid();return false}})}return b}else a&&a.debug&&window.console&&console.warn("nothing selected, can't validate, returning nothing")},valid:function(){if(c(this[0]).is("form"))return this.validate().form(); 256else{var a=true,b=c(this[0].form).validate();this.each(function(){a&=b.element(this)});return a}},removeAttrs:function(a){var b={},d=this;c.each(a.split(/\s/),function(e,f){b[f]=d.attr(f);d.removeAttr(f)});return b},rules:function(a,b){var d=this[0];if(a){var e=c.data(d.form,"validator").settings,f=e.rules,g=c.validator.staticRules(d);switch(a){case "add":c.extend(g,c.validator.normalizeRule(b));f[d.name]=g;if(b.messages)e.messages[d.name]=c.extend(e.messages[d.name],b.messages);break;case "remove":if(!b){delete f[d.name]; 257return g}var h={};c.each(b.split(/\s/),function(j,i){h[i]=g[i];delete g[i]});return h}}d=c.validator.normalizeRules(c.extend({},c.validator.metadataRules(d),c.validator.classRules(d),c.validator.attributeRules(d),c.validator.staticRules(d)),d);if(d.required){e=d.required;delete d.required;d=c.extend({required:e},d)}return d}});c.extend(c.expr[":"],{blank:function(a){return!c.trim(""+a.value)},filled:function(a){return!!c.trim(""+a.value)},unchecked:function(a){return!a.checked}});c.validator=function(a, 258b){this.settings=c.extend(true,{},c.validator.defaults,a);this.currentForm=b;this.init()};c.validator.format=function(a,b){if(arguments.length==1)return function(){var d=c.makeArray(arguments);d.unshift(a);return c.validator.format.apply(this,d)};if(arguments.length>2&&b.constructor!=Array)b=c.makeArray(arguments).slice(1);if(b.constructor!=Array)b=[b];c.each(b,function(d,e){a=a.replace(RegExp("\\{"+d+"\\}","g"),e)});return a};c.extend(c.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error", 259validClass:"valid",errorElement:"label",focusInvalid:true,errorContainer:c([]),errorLabelContainer:c([]),onsubmit:true,ignore:[],ignoreTitle:false,onfocusin:function(a){this.lastActive=a;if(this.settings.focusCleanup&&!this.blockFocusCleanup){this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass);this.addWrapper(this.errorsFor(a)).hide()}},onfocusout:function(a){if(!this.checkable(a)&&(a.name in this.submitted||!this.optional(a)))this.element(a)}, 260onkeyup:function(a){if(a.name in this.submitted||a==this.lastElement)this.element(a)},onclick:function(a){if(a.name in this.submitted)this.element(a);else a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(a,b,d){a.type==="radio"?this.findByName(a.name).addClass(b).removeClass(d):c(a).addClass(b).removeClass(d)},unhighlight:function(a,b,d){a.type==="radio"?this.findByName(a.name).removeClass(b).addClass(d):c(a).removeClass(b).addClass(d)}},setDefaults:function(a){c.extend(c.validator.defaults, 261a)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date (ISO).",number:"Please enter a valid number.",digits:"Please enter only digits.",creditcard:"Please enter a valid credit card number.",equalTo:"Please enter the same value again.",accept:"Please enter a value with a valid extension.",maxlength:c.validator.format("Please enter no more than {0} characters."), 262minlength:c.validator.format("Please enter at least {0} characters."),rangelength:c.validator.format("Please enter a value between {0} and {1} characters long."),range:c.validator.format("Please enter a value between {0} and {1}."),max:c.validator.format("Please enter a value less than or equal to {0}."),min:c.validator.format("Please enter a value greater than or equal to {0}.")},autoCreateRanges:false,prototype:{init:function(){function a(e){var f=c.data(this[0].form,"validator");e="on"+e.type.replace(/^validate/, 263"");f.settings[e]&&f.settings[e].call(f,this[0])}this.labelContainer=c(this.settings.errorLabelContainer);this.errorContext=this.labelContainer.length&&this.labelContainer||c(this.currentForm);this.containers=c(this.settings.errorContainer).add(this.settings.errorLabelContainer);this.submitted={};this.valueCache={};this.pendingRequest=0;this.pending={};this.invalid={};this.reset();var b=this.groups={};c.each(this.settings.groups,function(e,f){c.each(f.split(/\s/),function(g,h){b[h]=e})});var d=this.settings.rules;
264c.each(d,function(e,f){d[e]=c.validator.normalizeRule(f)});c(this.currentForm).validateDelegate(":text, :password, :file, select, textarea","focusin focusout keyup",a).validateDelegate(":radio, :checkbox, select, option","click",a);this.settings.invalidHandler&&c(this.currentForm).bind("invalid-form.validate",this.settings.invalidHandler)},form:function(){this.checkForm();c.extend(this.submitted,this.errorMap);this.invalid=c.extend({},this.errorMap);this.valid()||c(this.currentForm).triggerHandler("invalid-form", 265[this]);this.showErrors();return this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(a){this.lastElement=a=this.clean(a);this.prepareElement(a);this.currentElements=c(a);var b=this.check(a);if(b)delete this.invalid[a.name];else this.invalid[a.name]=true;if(!this.numberOfInvalids())this.toHide=this.toHide.add(this.containers);this.showErrors();return b},showErrors:function(a){if(a){c.extend(this.errorMap, 266a);this.errorList=[];for(var b in a)this.errorList.push({message:a[b],element:this.findByName(b)[0]});this.successList=c.grep(this.successList,function(d){return!(d.name in a)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){c.fn.resetForm&&c(this.currentForm).resetForm();this.submitted={};this.prepareForm();this.hideErrors();this.elements().removeClass(this.settings.errorClass)},numberOfInvalids:function(){return this.objectLength(this.invalid)}, 267objectLength:function(a){var b=0,d;for(d in a)b++;return b},hideErrors:function(){this.addWrapper(this.toHide).hide()},valid:function(){return this.size()==0},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{c(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(a){}},findLastActive:function(){var a=this.lastActive;return a&&c.grep(this.errorList,function(b){return b.element.name== 268a.name}).length==1&&a},elements:function(){var a=this,b={};return c(this.currentForm).find("input, select, textarea").not(":submit, :reset, :image, [disabled]").not(this.settings.ignore).filter(function(){!this.name&&a.settings.debug&&window.console&&console.error("%o has no name assigned",this);if(this.name in b||!a.objectLength(c(this).rules()))return false;return b[this.name]=true})},clean:function(a){return c(a)[0]},errors:function(){return c(this.settings.errorElement+"."+this.settings.errorClass, 269this.errorContext)},reset:function(){this.successList=[];this.errorList=[];this.errorMap={};this.toShow=c([]);this.toHide=c([]);this.currentElements=c([])},prepareForm:function(){this.reset();this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset();this.toHide=this.errorsFor(a)},check:function(a){a=this.clean(a);if(this.checkable(a))a=this.findByName(a.name).not(this.settings.ignore)[0];var b=c(a).rules(),d=false,e;for(e in b){var f={method:e,parameters:b[e]};try{var g= 270c.validator.methods[e].call(this,a.value.replace(/\r/g,""),a,f.parameters);if(g=="dependency-mismatch")d=true;else{d=false;if(g=="pending"){this.toHide=this.toHide.not(this.errorsFor(a));return}if(!g){this.formatAndAdd(a,f);return false}}}catch(h){this.settings.debug&&window.console&&console.log("exception occurred when checking element "+a.id+", check the '"+f.method+"' method",h);throw h;}}if(!d){this.objectLength(b)&&this.successList.push(a);return true}},customMetaMessage:function(a,b){if(c.metadata){var d= 271this.settings.meta?c(a).metadata()[this.settings.meta]:c(a).metadata();return d&&d.messages&&d.messages[b]}},customMessage:function(a,b){var d=this.settings.messages[a];return d&&(d.constructor==String?d:d[b])},findDefined:function(){for(var a=0;a<arguments.length;a++)if(arguments[a]!==undefined)return arguments[a]},defaultMessage:function(a,b){return this.findDefined(this.customMessage(a.name,b),this.customMetaMessage(a,b),!this.settings.ignoreTitle&&a.title||undefined,c.validator.messages[b],"<strong>Warning: No message defined for "+ 272a.name+"</strong>")}
272,formatAndAdd:function(a,b){var d=this.defaultMessage(a,b.method),e=/\$?\{(\d+)\}/g;if(typeof d=="function")d=d.call(this,b.parameters,a);else if(e.test(d))d=jQuery.format(d.replace(e,"{$1}"),b.parameters);this.errorList.push({message:d,element:a});this.errorMap[a.name]=d;this.submitted[a.name]=d},addWrapper:function(a){if(this.settings.wrapper)a=a.add(a.parent(this.settings.wrapper));return a},defaultShowErrors:function(){for(var a=0;this.errorList[a];a++){var b=this.errorList[a]; 273this.settings.highlight&&this.settings.highlight.call(this,b.element,this.settings.errorClass,this.settings.validClass);this.showLabel(b.element,b.message)}if(this.errorList.length)this.toShow=this.toShow.add(this.containers);if(this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight){a=0;for(b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass)}this.toHide=this.toHide.not(this.toShow); 274this.hideErrors();this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return c(this.errorList).map(function(){return this.element})},showLabel:function(a,b){var d=this.errorsFor(a);if(d.length){d.removeClass().addClass(this.settings.errorClass);d.attr("generated")&&d.html(b)}else{d=c("<"+this.settings.errorElement+"/>").attr({"for":this.idOrName(a),generated:true}).addClass(this.settings.errorClass).html(b|| 275"");if(this.settings.wrapper)d=d.hide().show().wrap("<"+this.settings.wrapper+"/>").parent();this.labelContainer.append(d).length||(this.settings.errorPlacement?this.settings.errorPlacement(d,c(a)):d.insertAfter(a))}if(!b&&this.settings.success){d.text("");typeof this.settings.success=="string"?d.addClass(this.settings.success):this.settings.success(d)}this.toShow=this.toShow.add(d)},errorsFor:function(a){var b=this.idOrName(a);return this.errors().filter(function(){return c(this).attr("for")==b})}, 276idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(a){var b=this.currentForm;return c(document.getElementsByName(a)).map(function(d,e){return e.form==b&&e.name==a&&e||null})},getLength:function(a,b){switch(b.nodeName.toLowerCase()){case "select":return c("option:selected",b).length;case "input":if(this.checkable(b))return this.findByName(b.name).filter(":checked").length}return a.length}, 277depend:function(a,b){return this.dependTypes[typeof a]?this.dependTypes[typeof a](a,b):true},dependTypes:{"boolean":function(a){return a},string:function(a,b){return!!c(a,b.form).length},"function":function(a,b){return a(b)}},optional:function(a){return!c.validator.methods.required.call(this,c.trim(a.value),a)&&"dependency-mismatch"},startRequest:function(a){if(!this.pending[a.name]){this.pendingRequest++;this.pending[a.name]=true}},stopRequest:function(a,b){this.pendingRequest--;if(this.pendingRequest< 2780)this.pendingRequest=0;delete this.pending[a.name];if(b&&this.pendingRequest==0&&this.formSubmitted&&this.form()){c(this.currentForm).submit();this.formSubmitted=false}else if(!b&&this.pendingRequest==0&&this.formSubmitted){c(this.currentForm).triggerHandler("invalid-form",[this]);this.formSubmitted=false}},previousValue:function(a){return c.data(a,"previousValue")||c.data(a,"previousValue",{old:null,valid:true,message:this.defaultMessage(a,"remote")})}},classRuleSettings:{required:{required:true}, 279email:{email:true},url:{url:true},date:{date:true},dateISO:{dateISO:true},dateDE:{dateDE:true},number:{number:true},numberDE:{numberDE:true},digits:{digits:true},creditcard:{creditcard:true}},addClassRules:function(a,b){a.constructor==String?this.classRuleSettings[a]=b:c.extend(this.classRuleSettings,a)},classRules:function(a){var b={};(a=c(a).attr("class"))&&c.each(a.split(" "),function(){this in c.validator.classRuleSettings&&c.extend(b,c.validator.classRuleSettings[this])});return b},attributeRules:function(a){var b= 280{};a=c(a);for(var d in c.validator.methods){var e=a.attr(d);if(e)b[d]=e}b.maxlength&&/-1|2147483647|524288/.test(b.maxlength)&&delete b.maxlength;return b}
280,metadataRules:function(a){if(!c.metadata)return{};var b=c.data(a.form,"validator").settings.meta;return b?c(a).metadata()[b]:c(a).metadata()},staticRules:function(a){var b={},d=c.data(a.form,"validator");if(d.settings.rules)b=c.validator.normalizeRule(d.settings.rules[a.name])||{};return b},normalizeRules:function(a,b){c.each(a,function(d,e){if(e=== 281false)delete a[d];else if(e.param||e.depends){var f=true;switch(typeof e.depends){case "string":f=!!c(e.depends,b.form).length;break;case "function":f=e.depends.call(b,b)}if(f)a[d]=e.param!==undefined?e.param:true;else delete a[d]}});c.each(a,function(d,e){a[d]=c.isFunction(e)?e(b):e});c.each(["minlength","maxlength","min","max"],function(){if(a[this])a[this]=Number(a[this])});c.each(["rangelength","range"],function(){if(a[this])a[this]=[Number(a[this][0]),Number(a[this][1])]});if(c.validator.autoCreateRanges){if(a.min&& 282a.max){a.range=[a.min,a.max];delete a.min;delete a.max}if(a.minlength&&a.maxlength){a.rangelength=[a.minlength,a.maxlength];delete a.minlength;delete a.maxlength}}a.messages&&delete a.messages;return a},normalizeRule:function(a){if(typeof a=="string"){var b={};c.each(a.split(/\s/),function(){b[this]=true});a=b}return a},addMethod:function(a,b,d){c.validator.methods[a]=b;c.validator.messages[a]=d!=undefined?d:c.validator.messages[a];b.length<3&&c.validator.addClassRules(a,c.validator.normalizeRule(a))}, 283methods:{required:function(a,b,d){if(!this.depend(d,b))return"dependency-mismatch";switch(b.nodeName.toLowerCase()){case "select":return(a=c(b).val())&&a.length>0;case "input":if(this.checkable(b))return this.getLength(a,b)>0;default:return c.trim(a).length>0}},remote:function(a,b,d){if(this.optional(b))return"dependency-mismatch";var e=this.previousValue(b);this.settings.messages[b.name]||(this.settings.messages[b.name]={});e.originalMessage=this.settings.messages[b.name].remote;this.settings.messages[b.name].remote= 284e.message;d=typeof d=="string"&&{url:d}||d;if(this.pending[b.name])return"pending";if(e.old===a)return e.valid;e.old=a;var f=this;this.startRequest(b);var g={};g[b.name]=a;c.ajax(c.extend(true,{url:d,mode:"abort",port:"validate"+b.name,dataType:"json",data:g,success:function(h){f.settings.messages[b.name].remote=e.originalMessage;var j=h===true;if(j){var i=f.formSubmitted;f.prepareElement(b);f.formSubmitted=i;f.successList.push(b);f.showErrors()}else{i={};h=h||f.defaultMessage(b,"remote");i[b.name]= 285e.message=c.isFunction(h)?h(a):h;f.showErrors(i)}e.valid=j;f.stopRequest(b,j)}},d));return"pending"},minlength:function(a,b,d){return this.optional(b)||this.getLength(c.trim(a),b)>=d},maxlength:function(a,b,d){return this.optional(b)||this.getLength(c.trim(a),b)<=d},rangelength:function(a,b,d){a=this.getLength(c.trim(a),b);return this.optional(b)||a>=d[0]&&a<=d[1]},min:function(a,b,d){return this.optional(b)||a>=d},max:function(a,b,d){return this.optional(b)||a<=d},range:function(a,b,d){return this.optional(b)|| 286a>=d[0]&&a<=d[1]},email:function(a,b){return this.optional(b)||/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(a)}, 287url:function(a,b){return this.optional(b)||/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a)}, 288date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a))},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(a)},number:function(a,b){return this.optional(b)||/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},creditcard:function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9-]+/.test(a))return false;var d=0,e=0,f=false;a=a.replace(/\D/g,"");for(var g=a.length-1;g>= 2890;g--){e=a.charAt(g);e=parseInt(e,10);if(f)if((e*=2)>9)e-=9;d+=e;f=!f}return d%10==0}
289,accept:function(a,b,d){d=typeof d=="string"?d.replace(/,/g,"|"):"png|jpe?g|gif";return this.optional(b)||a.match(RegExp(".("+d+")$","i"))},equalTo:function(a,b,d){d=c(d).unbind(".validate-equalTo").bind("blur.validate-equalTo",function(){c(b).valid()});return a==d.val()}}});c.format=c.validator.format})(jQuery); 290(function(c){var a={};if(c.ajaxPrefilter)c.ajaxPrefilter(function(d,e,f){e=d.port;if(d.mode=="abort"){a[e]&&a[e].abort();a[e]=f}});else{var b=c.ajax;c.ajax=function(d){var e=("port"in d?d:c.ajaxSettings).port;if(("mode"in d?d:c.ajaxSettings).mode=="abort"){a[e]&&a[e].abort();return a[e]=b.apply(this,arguments)}return b.apply(this,arguments)}}})(jQuery); 291(function(c){!jQuery.event.special.focusin&&!jQuery.event.special.focusout&&document.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(e){e=c.event.fix(e);e.type=b;return c.event.handle.call(this,e)}c.event.special[b]={setup:function(){this.addEventListener(a,d,true)},teardown:function(){this.removeEventListener(a,d,true)},handler:function(e){arguments[0]=c.event.fix(e);arguments[0].type=b;return c.event.handle.apply(this,arguments)}}});c.extend(c.fn,{validateDelegate:function(a, 292b,d){return this.bind(b,function(e){var f=c(e.target);if(f.is(a))return d.apply(f,arguments)})}})})(jQuery); 293 294 295/** 296* jQuery Validation Plugin 1.8.1 "ADDITIONAL METHODS" 297* 298* http://bassistance.de/jquery-plugins/jquery-plugin-validation/ 299* http://docs.jquery.com/Plugins/Validation 300* 301* Copyright (c) 2006 - 2011 Jörn Zaefferer 302* 303* Dual licensed under the MIT and GPL licenses: 304* http://www.opensource.org/licenses/mit-license.php 305* http://www.gnu.org/licenses/gpl.html 306*/ 307(function () { 308 function a(b) { return b.replace(/<.[^<>]*?>/g, " ").replace(/ | /gi, " ").replace(/[0-9.(),;:!?%#$'"_+=\/-]*/g, "") } jQuery.validator.addMethod("maxWords", function (b, c, d) { return this.optional(c) || a(b).match(/\b\w+\b/g).length < d }, jQuery.validator.format("Please enter {0} words or less.")); jQuery.validator.addMethod("minWords", function (b, c, d) { return this.optional(c) || a(b).match(/\b\w+\b/g).length >= d }, jQuery.validator.format("Please enter at least {0} words.")); jQuery.validator.addMethod("rangeWords", 309function (b, c, d) { return this.optional(c) || a(b).match(/\b\w+\b/g).length >= d[0] && b.match(/bw+b/g).length < d[1] }, jQuery.validator.format("Please enter between {0} and {1} words.")) 310})(); jQuery.validator.addMethod("letterswithbasicpunc", function (a, b) { return this.optional(b) || /^[a-z-.,()'\"\s]+$/i.test(a) }, "Letters or punctuation only please"); jQuery.validator.addMethod("alphanumeric", function (a, b) { return this.optional(b) || /^\w+$/i.test(a) }, "Letters, numbers, spaces or underscores only please"); 311jQuery.validator.addMethod("lettersonly", function (a, b) { return this.optional(b) || /^[a-z]+$/i.test(a) }, "Letters only please"); jQuery.validator.addMethod("nowhitespace", function (a, b) { return this.optional(b) || /^\S+$/i.test(a) }, "No white space please"); jQuery.validator.addMethod("ziprange", function (a, b) { return this.optional(b) || /^90[2-5]\d\{2}-\d{4}$/.test(a) }, "Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx"); 312jQuery.validator.addMethod("integer", function (a, b) { return this.optional(b) || /^-?\d+$/.test(a) }, "A positive or negative non-decimal number please"); 313jQuery.validator.addMethod("vinUS", function (a) { if (a.length != 17) return false; var b, c, d, f, e, g = ["A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"], i = [1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 7, 9, 2, 3, 4, 5, 6, 7, 8, 9], j = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2], h = 0; for (b = 0; b < 17; b++) { f = j[b]; d = a.slice(b, b + 1); if (b == 8) e = d; if (isNaN(d)) for (c = 0; c < g.length; c++) { if (d.toUpperCase() === g[c]) { d = i[c]; d *= f; if (isNaN(e) && c == 8) e = g[c]; break } } else d *= f; h += d } a = h % 11; if (a == 10) a = "X"; if (a == e) return true; return false },
314"The specified vehicle identification number (VIN) is invalid."); jQuery.validator.addMethod("dateITA", function (a, b) { var c = false; if (/^\d{1,2}\/\d{1,2}\/\d{4}$/.test(a)) { var d = a.split("/"); c = parseInt(d[0], 10); var f = parseInt(d[1], 10); d = parseInt(d[2], 10); var e = new Date(d, f - 1, c); c = e.getFullYear() == d && e.getMonth() == f - 1 && e.getDate() == c ? true : false } else c = false; return this.optional(b) || c }, "Please enter a correct date"); 315jQuery.validator.addMethod("dateNL", function (a, b) { return this.optional(b) || /^\d\d?[\.\/-]\d\d?[\.\/-]\d\d\d?\d?$/.test(a) }, "Vul hier een geldige datum in."); jQuery.validator.addMethod("time", function (a, b) { return this.optional(b) || /^([01][0-9])|(2[0123]):([0-5])([0-9])$/.test(a) }, "Please enter a valid time, between 00:00 and 23:59"); 316jQuery.validator.addMethod("phoneUS", function (a, b) { a = a.replace(/\s+/g, ""); return this.optional(b) || a.length > 9 && a.match(/^(1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/) }, "Please specify a valid phone number"); jQuery.validator.addMethod("phoneUK", function (a, b) { return this.optional(b) || a.length > 9 && a.match(/^(\(?(0|\+44)[1-9]{1}\d{1,4}?\)?\s?\d{3,4}\s?\d{3,4})$/) }, "Please specify a valid phone number"); 317jQuery.validator.addMethod("mobileUK", function (a, b) { return this.optional(b) || a.length > 9 && a.match(/^((0|\+44)7(5|6|7|8|9){1}\d{2}\s?\d{6})$/) }, "Please specify a valid mobile number"); jQuery.validator.addMethod("strippedminlength", function (a, b, c) { return jQuery(a).text().length >= c }, jQuery.validator.format("Please enter at least {0} characters")); 318jQuery.validator.addMethod("email2", function (a, b) { return this.optional(b) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(a) }, jQuery.validator.messages.email); 319jQuery.validator.addMethod("url2", function (a, b) { return this.optional(b) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a) }, 320jQuery.validator.messages.url); 321jQuery.validator.addMethod("creditcardtypes", function (a, b, c) { 322 if (/[^0-9-]+/.test(a)) return false; a = a.replace(/\D/g, ""); b = 0; if (c.mastercard) b |= 1; if (c.visa) b |= 2; if (c.amex) b |= 4; if (c.dinersclub) b |= 8; if (c.enroute) b |= 16; if (c.discover) b |= 32; if (c.jcb) b |= 64; if (c.unknown) b |= 128; if (c.all) b = 255; if (b & 1 && /^(51|52|53|54|55)/.test(a)) return a.length == 16; if (b & 2 && /^(4)/.test(a)) return a.length == 16; if (b & 4 && /^(34|37)/.test(a)) return a.length == 15; if (b & 8 && /^(300|301|302|303|304|305|36|38)/.test(a)) return a.length == 14; if (b & 32316 && /^(2014|2149)/.test(a)) return a.length == 15; if (b & 32 && /^(6011)/.test(a)) return a.length == 16; if (b & 64 && /^(3)/.test(a)) return a.length == 16; if (b & 64 && /^(2131|1800)/.test(a)) return a.length == 15; if (b & 128) return true; return false 324}, "Please enter a valid credit card number."); 325jQuery.validator.addMethod("ipv4", function (a, b) { return this.optional(b) || /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i.test(a) }, "Please enter a valid IP v4 address."); 326jQuery.validator.addMethod("ipv6", function (a, b) { return this.optional(b) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(a) }, "Please enter a valid IP v6 address."); 327 328 329; 330////pf: javascript/jquery.tmpl.min.js 331/* 332* jQuery Templates Plugin 1.0.0pre 333* http://github.com/jquery/jquery-tmpl 334* Requires jQuery 1.4.2 335*
336* Copyright Software Freedom Conservancy, Inc. 337* Dual licensed under the MIT or GPL Version 2 licenses. 338* http://jquery.org/license 339*/ 340(function (a) { var r = a.fn.domManip, d = "_tmplitem", q = /^[^<]*(<[\w\W]+>)[^>]*$|\{\{\! /, b = {}, f = {}, e, p = { key: 0, data: {} }, i = 0, c = 0, l = []; function g(g, d, h, e) { var c = { data: e || (e === 0 || e === false) ? e : d ? d.data : {}, _wrap: d ? d._wrap : null, tmpl: null, parent: d || null, nodes: [], calls: u, nest: w, wrap: x, html: v, update: t }; g && a.extend(c, g, { nodes: [], parent: d }); if (h) { c.tmpl = h; c._ctnt = c._ctnt || c.tmpl(a, c); c.key = ++i; (l.length ? f : b)[i] = c } return c } a.each({ appendTo: "append", prependTo: "prepend", insertBefore: "before", insertAfter: "after", replaceAll: "replaceWith" }, function (f, d) { a.fn[f] = function (n) { var g = [], i = a(n), k, h, m, l, j = this.length === 1 && this[0].parentNode; e = b || {}; if (j && j.nodeType === 11 && j.childNodes.length === 1 && i.length === 1) { i[d](this[0]); g = this } else { for (h = 0, m = i.length; h < m; h++) { c = h; k = (h > 0 ? this.clone(true) : this).get(); a(i[h])[d](k); g = g.concat(k) } c = 0; g = this.pushStack(g, f, i.selector) } l = e; e = null; a.tmpl.complete(l); return g } }); a.fn.extend({ tmpl: function (d, c, b) { return a.tmpl(this[0], d, c, b) }, tmplItem: function () { return a.tmplItem(this[0]) }, template: function (b) { return a.template(b, this[0]) }, domManip: function (d, m, k) { if (d[0] && a.isArray(d[0])) { var g = a.makeArray(arguments), h = d[0], j = h.length, i = 0, f; while (i < j && !(f = a.data(h[i++], "tmplItem"))); if (f && c) g[2] = function (b) { a.tmpl.afterManip(this, b, k) }; r.apply(this, g) } else r.apply(this, arguments); c = 0; !e && a.tmpl.complete(b); return this } }); a.extend({ tmpl: function (d, h, e, c) { var i, k = !c; if (k) { c = p; d = a.template[d] || a.template(null, d); f = {} } else if (!d) { d = c.tmpl; b[c.key] = c; c.nodes = []; c.wrapped && n(c, c.wrapped); return a(j(c, null, c.tmpl(a, c))) } if (!d) return []; if (typeof h === "function") h = h.call(c || {}); e && e.wrapped && n(e, e.wrapped); i = a.isArray(h) ? a.map(h, function (a) { return a ? g(e, c, d, a) : null }) : [g(e, c, d, h)]; return k ? a(j(c, null, i)) : i }, tmplItem: function (b) { var c; if (b instanceof a) b = b[0]; while (b && b.nodeType === 1 && !(c = a.data(b, "tmplItem")) && (b = b.parentNode)); return c || p }, template: function (c, b) { if (b) { if (typeof b === "string") b = o(b); else if (b instanceof a) b = b[0] || {}; if (b.nodeType) b = a.data(b, "tmpl") || a.data(b, "tmpl", o(b.innerHTML)); return typeof c === "string" ? (a.template[c] = b) : b } return c ? typeof c !== "string" ? a.template(null, c) : a.template[c] || a.template(null, q.test(c) ? c : a(c)) : null }, encode: function (a) { return ("" + a).split("<").join("<").split(">").join(">").split('"').join(""").split("'").join("'") } }); a.extend(a.tmpl, { tag: { tmpl: { _default: { $2: "null" }, open: "if($notnull_1){__=__.concat($item.nest($1,$2));}" }, wrap: { _default: { $2: "null" }, open: "$item.calls(__,$1,$2);__=[];", close: "call=$item.calls();__=call._.concat($item.wrap(call,__));" }, each: { _default: { $2: "$index, $value" }, open: "if($notnull_1){$.each($1a,function($2){with(this){", close: "}});}" }, "if": { open: "if(($notnull_1) && $1a){", close: "}" }, "else": { _default: { $1: "true" }, open: "}else if(($notnull_1) && $1a){" }, html: { open: "if($notnull_1){__.push($1a);}" }, "=": { _default: { $1: "$data" }, open: "if($notnull_1){__.push($.encode($1a));}" }, "!": { open: ""} }, complete: function () { b = {} }, afterManip: function (f, b, d) { var e = b.nodeType === 11 ? a.makeArray(b.childNodes) : b.nodeType === 1 ? [b] : []; d.call(f, b); m(e); c++ } }); function j(e, g, f) { var b, c = f ? a.map(f, function (a) { return typeof a === "string" ? e.key ? a.replace(/(<\w+)(?=[\s>])(?![^>]*_tmplitem)([^>]*)/g, "$1 " + d + '="' + e.key + '" $2') : a : j(a, e, a._ctnt) }) : e; if (g) return c; c = c.join(""); c.replace(/^\s*([^<\s][^<]*)?(<[\w\W]+>)([^>]*[^>\s])?\s*$/, function (f, c, e, d) { b = a(e).get(); m(b); if (c) b = k(c).concat(b); if (d) b = b.concat(k(d)) }); return b ? b : k(c) } function k(c) { var b = document.createElement("div"); b.innerHTML = c; return a.makeArray(b.childNodes) } function o(b) { return new Function("jQuery", "$item", "var $=jQuery,call,__=[],$data=$item.data;with($data){__.push('" + a.trim(b).replace(/([\\'])/g, "\\$1").replace(/[\r\t\n]/g, " ").replace(/\$\{([^\}]*)\}/g, "{{= $1}}").replace(/\{\{(\/?)(\w+|.)(?:\(((?:[^\}]|\}(?!\}))*?)?\))?(?:\s+(.*?)?)?(\(((?:[^\}]|\}(?!\}))*?)\))?\s*\}\}/g, function (m, l, k, g, b, c, d) { var j = a.tmpl.tag[k], i, e, f; if (!j) throw "Unknown template tag: " + k; i = j._default || []; if (c && !/\w$/.test(b)) { b += c; c = "" } if (b) { b = h(b); d = d ? "," + h(d) + ")" : c ? ")" : ""; e = c ? b.indexOf(".") > -1 ? b + h(c) : "(" + b + ").call($item" + d : b; f = c ? e : "(typeof(" + b + ")==='function'?(" + b + ").call($item):(" + b + "))" } else f = e = i.$1 || "null"; g = h(g); return "');" + j[l ? "close" : "open"].split("$notnull_1").join(b ? "typeof(" + b + ")!=='undefined' && (" + b + ")!=null" : "true").split("$1a").join(f).split("$1").join(e).split("$2").join(g || i.$2 || "") + "__.push('" }) + "');}return __;") } function n(c, b) { c._wrap = j(c, true, a.isArray(b) ? b : [q.test(b) ? b : a(b).html()]).join("") } function h(a) { return a ? a.replace(/\\'/g, "'").replace(/\\\\/g, "\\") : null } function s(b) { var a = document.createElement("div"); a.appendChild(b.cloneNode(true)); return a.innerHTML } function m(o) { var n = "_" + c, k, j, l = {}, e, p, h; for (e = 0, p = o.length; e < p; e++) { if ((k = o[e]).nodeType !== 1) continue; j = k.getElementsByTagName("*"); for (h = j.length - 1; h >= 0; h--) m(j[h]); m(k) } function m(j) { var p, h = j, k, e, m; if (m = j.getAttribute(d)) { while (h.parentNode && (h = h.parentNode).nodeType === 1 && !(p = h.getAttribute(d))); if (p !== m) { h = h.parentNode ? h.nodeType === 11 ? 0 : h.getAttribute(d) || 0 : 0; if (!(e = b[m])) { e = f[m]; e = g(e, b[h] || f[h]); e.key = ++i; b[i] = e } c && o(m) } j.removeAttribute(d) } else if (c && (e = a.data(j, "tmplItem"))) { o(e.key); b[e.key] = e; h = a.data(j.parentNode, "tmplItem"); h = h ? h.key : 0 } if (e) { k = e; while (k && k.key != h) { k.nodes.push(j); k = k.parent } delete e._ctnt; delete e._wrap; a.data(j, "tmplItem", e) } function o(a) { a = a + n; e = l[a] = l[a] || g(e, b[e.parent.key + n] || e.parent) } } } function u(a, d, c, b) { if (!a) return l.pop(); l.push({ _: a, tmpl: d, item: this, data: c, options: b }) } function w(d, c, b) { return a.tmpl(a.template(d), c, b, this) } function x(b, d) { var c = b.options || {}; c.wrapped = d; return a.tmpl(a.template(b.tmpl), b.data, c, b.item) } function v(d, c) { var b = this._wrap; return a.map(a(a.isArray(b) ? b.join("") : b).filter(d || "*"), function (a) { return c ? a.innerText || a.textContent : a.outerHTML || s(a) }) } function t() { var b = this.nodes; a.tmpl(null, null, null, this).insertBefore(b[0]); a(b).remove() } })(jQuery); 341 342; 343////pf: masters/themes/clean/main.js 344// silence mobile safari error 345window._AutofillCallbackHandler = 346 window._AutofillCallbackHandler || function () {}; 347 348$(function () { 349 const topNavHeight = parseInt($("#TopNav").css("height")); 350 351 let subNavWaypoint; 352 const subNavWrapper = document.querySelector("#SubNavWrapper"); 353 const subNav = document.querySelector("#SubNav"); 354 const hasChildren = !!subNav?.children.length; 355 if (subNavWrapper && hasChildren) { 356 subNavWrapper.setAttribute("style", "height: var(--subNav-height);"); 357 subNavWaypoint = new Waypoint({ 358 element: subNavWrapper, 359 offset: topNavHeight, 360 handler: function (direction) { 361 $("html").toggleClass("PinSubNav", direction === "down"); 362 }, 363 });
364 365 // Initialize horizontal scrolling for tabs 366 initializeTabScrolling(subNav); 367 } else if (subNavWrapper) { 368 subNavWrapper.setAttribute("style", "display: none;"); 369 } 370 371 window.disableSubNavWaypoint = () => { 372 if (subNavWaypoint) { 373 $("html").removeClass("PinSubNav"); 374 subNavWaypoint.disable(); 375 } 376 }; 377 window.enableSubNavWaypoint = () => { 378 if (subNavWaypoint) { 379 subNavWaypoint.enable(); 380 } 381 }; 382 383 function initializeTabScrolling(subNav) { 384 const list = subNav.querySelector("ul, ol"); 385 const scrollContainer = document.createElement("div"); 386 scrollContainer.className = "grit-tabs-scroll-container"; 387 388 const scrollWrapper = document.createElement("div"); 389 scrollWrapper.className = "grit-tabs-scroll-wrapper"; 390 scrollWrapper.appendChild(scrollContainer); 391 392 if (list) { 393 list.parentNode.insertBefore(scrollWrapper, list); 394 scrollContainer.appendChild(list); 395 } else { 396 const children = Array.from(subNav.children).filter( 397 (child) => !child.classList.contains("grit-tabs-scroll-arrow") 398 ); 399 400 if (children.length === 0) return; 401 402 subNav.insertBefore(scrollWrapper, children[0]); 403 404 children.forEach((child) => scrollContainer.appendChild(child)); 405 } 406 407 const leftArrow = document.createElement("button"); 408 leftArrow.className = "grit-tabs-scroll-arrow left hidden"; 409 leftArrow.innerHTML = '<i class="fas fa-chevron-left"></i>'; 410 leftArrow.setAttribute("type", "button"); 411 leftArrow.setAttribute("aria-label", "Scroll left"); 412 413 const rightArrow = document.createElement("button"); 414 rightArrow.className = "grit-tabs-scroll-arrow right hidden"; 415 rightArrow.innerHTML = '<i class="fas fa-chevron-right"></i>'; 416 rightArrow.setAttribute("type", "button"); 417 rightArrow.setAttribute("aria-label", "Scroll right"); 418 419 scrollWrapper.appendChild(leftArrow); 420 scrollWrapper.appendChild(rightArrow); 421 422 const getArrowWidth = () => { 423 const leftWidth = leftArrow.offsetWidth || leftArrow.getBoundingClientRect().width; 424 const rightWidth = rightArrow.offsetWidth || rightArrow.getBoundingClientRect().width; 425 return leftWidth || rightWidth; 426 }; 427 428 function getTabElements() { 429 const list = scrollContainer.querySelector("ul, ol"); 430 if (list) { 431 return Array.from(list.querySelectorAll("li")); 432 } 433 return Array.from(scrollContainer.children).filter( 434 (child) => !child.classList.contains("grit-tabs-scroll-arrow") 435 ); 436 } 437 438 function scrollToNextTab(direction) { 439 const tabs = getTabElements(); 440 if (tabs.length === 0) return; 441 442 const arrowWidth = getArrowWidth(); 443 const containerLeft = scrollContainer.scrollLeft; 444 const visibleLeft = containerLeft + arrowWidth; 445 const visibleRight = containerLeft + scrollContainer.clientWidth - arrowWidth; 446 447 let targetTab = null; 448 449 if (direction === "right") { 450 targetTab = tabs.find(tab => { 451 const tabRight = tab.offsetLeft + tab.offsetWidth; 452 return tabRight > visibleRight; 453 }); 454 455 if (targetTab) { 456 scrollContainer.scrollBy({ 457 left: targetTab.offsetLeft - visibleLeft, 458 behavior: "smooth", 459 }); 460 } 461 } else { 462 targetTab = [...tabs].reverse().find(tab => { 463 return tab.offsetLeft < visibleLeft; 464 }); 465 466 if (targetTab) { 467 const tabRight = targetTab.offsetLeft + targetTab.offsetWidth; 468 scrollContainer.scrollBy({ 469 left: tabRight - visibleRight, 470 behavior: "smooth", 471 }); 472 } 473 } 474 } 475 476 leftArrow.addEventListener("click", () => scrollToNextTab("left")); 477 rightArrow.addEventListener("click", () => scrollToNextTab("right")); 478 479 function updateArrows() { 480 const { scrollLeft, scrollWidth, clientWidth }
480 = scrollContainer; 481 const hasOverflow = scrollWidth > clientWidth; 482 483 if (!hasOverflow) { 484 leftArrow.classList.add("hidden"); 485 rightArrow.classList.add("hidden"); 486 } else { 487 if (scrollLeft <= 1) { 488 leftArrow.classList.add("hidden"); 489 } else { 490 leftArrow.classList.remove("hidden"); 491 } 492 493 if (scrollLeft + clientWidth >= scrollWidth - 1) { 494 rightArrow.classList.add("hidden"); 495 } else { 496 rightArrow.classList.remove("hidden"); 497 } 498 } 499 } 500 501 scrollContainer.addEventListener("scroll", updateArrows); 502 503 window.addEventListener("resize", updateArrows); 504 window.addEventListener("startPageEditing", () => { 505 setTimeout(updateArrows, 100); 506 }); 507 window.addEventListener("updateScrollArrows", updateArrows); 508 509 setTimeout(updateArrows, 200); 510 511 subNav.dataset.scrollContainer = "initialized"; 512 subNav._scrollContainer = scrollContainer; 513 } 514 515 $(".playmakers li").on("click", function () { 516 if ("touchstart" in window) { 517 $(".playmakers li").removeClass("active"); 518 $(this).addClass("active"); 519 } 520 }); 521 522 $("html").addClass( 523 "os-" + 524 (navigator.userAgent.match("Windows") 525 ? "win" 526 : navigator.userAgent.match("Mac") 527 ? "mac" 528 : "") 529 ); 530 531 var cents = 0; 532 setInterval(function () { 533 $(".ticker").each(function () { 534 var start = Date.parse($(this).data("start")); 535 var end = Date.parse($(this).data("end")); 536 var now = Date.now(); 537 var pct = (now - start) / (end - start); 538 var min = $(this).data("min"); 539 var max = $(this).data("max"); 540 var baseValue = min + pct * (max - min); 541 var value = "$" + Math.min(max, baseValue + cents / 100).toFixed(2); 542 cents++; 543 544 $(this).html( 545 value 546 .split("") 547 .map(function (a) { 548 return "<span>" + a + "</span>"; 549 }) 550 .join("") 551 ); 552 }); 553 }, 200); 554 555 $("body").toggleClass( 556 "wrapper-has-jumbo", 557 $("#Wrapper .jumbo").index() === 0 558 ); 559}); 560 561 562; 563////pf: masters/themes/grit/footer/footer.js 564$(function () { 565 const $sponsorCarousel = $('.sponsor-carousel'); 566 const numChildren = $sponsorCarousel.children().length; 567 if (numChildren < 2) return; 568 $sponsorCarousel.slick({ 569 autoplay: true, 570 autoplaySpeed: 5000, 571 dots: false, 572 infinite: true, 573 slidesToShow: Math.min(5, numChildren - 1), 574 slidesToScroll: 1, 575 responsive: [ 576 { 577 breakpoint: 1180, 578 settings: { 579 slidesToShow: Math.min(3, numChildren - 1), 580 } 581 }, 582 { 583 breakpoint: 870, 584 settings: { 585 slidesToShow: Math.min(2, numChildren - 1) 586 } 587 }, 588 { 589 breakpoint: 600, 590 settings: { 591 slidesToShow: 1 592 } 593 } 594 ] 595 }) 596}) 597 598 599; 600////pf: masters/themes/grit/top-nav/top-nav.ts 601function getNavAndPosition() { 602 const mainNav = $("#TopNav"); 603 mainNav.removeClass("scrolled"); 604 const initPosition = mainNav.offset()?.top ?? 0; 605 return [mainNav, initPosition]; 606} 607 608function toggleScrollClass(mainNav, initPosition) { 609 const windowScroll = 610 window.scrollY || 611 document.documentElement.scrollTop || 612 document.body.scrollTop || 613 0; 614 mainNav.toggleClass("scrolled", windowScroll > initPosition); 615} 616 617function initToggleScrolledListener() { 618 const [mainNav, initPosition] = getNavAndPosition(); 619 toggleScrollClass(mainNav, initPosition); 620 $(window).on("scroll", function () { 621 const editingContainer = document.querySelector('#Wrapper.editing') 622 if (!editingContainer) { 623 toggleScrollClass(mainNav, initPosition); 624 } else { 625 // @ts-expect-error mainNav being typed as number | JQueryElement for some reason 626 mainNav.removeClass("scrolled"); 627 } 628 }); 629} 630// Add "active" class to the current page's nav link 631function toggleActiveClass() { 632 const mainNav = $("#MainNav"); 633 const activeNavLi = mainNav.find("li").filter((index, element) => { 634 const linkHref = $(element).find("a").attr("href"); 635 if (!linkHref) return false; 636 637 const currentPath = window.location.pathname; 638 const currentSearch = window.location.search; 639 const currentUrl = currentPath + currentSearch; 640 function isSame(a, b) { 641 return a.toLowerCase() === b.toLowerCase(); 642 } 643 644 if (linkHref.indexOf("?") === -1 && currentSearch === "") { 645 return isSame(linkHref, currentPath); 646 } 647 return isSame(linkHref, currentUrl); 648 }); 649 activeNavLi.addClass("active"); 650} 651 652function calcChildListsPositions() { 653 const $childLists = $(".list-parent > .child-item-list"); 654 const $childListsWithGrandchildren = $childLists.filter(function () { 655 return $(this).find(".child-item-list").length > 0;
656 }) 657 // Check if the grandchild list is out of view on the right of the viewport & if so apply "open-left" class 658 $childListsWithGrandchildren.each(function () { 659 const $grandchildList = $(this).find(".child-item-list"); 660 const width = $grandchildList[0].offsetWidth; 661 const left = $grandchildList.offset()?.left ?? 0; 662 if (left + width >= window.innerWidth - 24) { 663 $(this).addClass("open-left"); 664 } 665 }); 666} 667 668function initTopNav() { 669 initToggleScrolledListener(); 670 toggleActiveClass(); 671 calcChildListsPositions(); 672} 673 674$(function () { 675 initTopNav(); 676 677 $(window).on("resize", calcChildListsPositions); 678 679 // handle clicks outside of the mobile nav drawer 680 $(document).on("click", function (e) { 681 const $mobileNavToggle = $("#MobileNavToggle"); 682 if (!$mobileNavToggle.length || !$mobileNavToggle.is(":checked")) return; 683 if ( 684 !( 685 $(e.target).is($mobileNavToggle) || 686 $(e.target).closest("label[for='MobileNavToggle']").length || 687 $(e.target).is(".fas.fa-bars") 688 ) 689 ) { 690 if (!$(e.target).closest(".mobile-nav-drawer").length) { 691 $mobileNavToggle.prop("checked", false); 692 } 693 } 694 }); 695}); 696 697function closeMobileNav() { 698 const $mobileNavToggle = $("#MobileNavToggle"); 699 $mobileNavToggle.prop("checked", false); 700} 701 702function toggleNavSection(element) { 703 // Close all other open sections first 704 var allNavItems = document.querySelectorAll(".nav-item"); 705 allNavItems.forEach(function (item) { 706 if (item !== element.parentElement) { 707 item.classList.remove("expanded"); 708 var childList = item.querySelector(".nav-children"); 709 if (childList) { 710 $(childList).slideUp(300); 711 } 712 } 713 }); 714 715 // Toggle current section 716 var parentLi = element.parentElement; 717 parentLi?.classList.toggle("expanded"); 718 var childList = parentLi?.querySelector(".nav-children"); 719 if (childList) { 720 $(childList).slideToggle(300); 721 } 722} 723 724 725; 726////pf: masters/themes/grit/table/grit-table.js 727(function (window, document) { 728 "use strict"; 729 730 const DATA_ATTR = "data-grit-table"; 731 const DEFAULTS = { 732 filter: "none", 733 sort: "none", 734 pagination: "none", 735 pageSize: 25, 736 initialPage: 1, 737 }; 738 const MODES = { 739 server: new Set(["server"]), 740 client: new Set(["client"]), 741 all: new Set(["client", "server", "none"]), 742 }; 743 const SORT_DIRS = ["asc", "desc"]; 744 const CLASSES = { loading: "is-loading", hidden: "is-hidden" }; 745 // Explicit format allowlist for strict parsing via moment(), so plain numbers 746 // or arbitrary text aren't mistaken for dates during column-type guessing. 747 const DATE_FORMATS = [ 748 "MM/DD/YYYY", 749 "M/D/YYYY", 750 "MM/DD/YY", 751 "M/D/YY", 752 "YYYY-MM-DD", 753 "MMM D, YYYY", 754 "MMMM D, YYYY", 755 "MMM D YYYY", 756 "DD-MMM-YYYY", 757 "MMM D", 758 "MMMM D", 759 ]; 760 const DATE_RANGE_PATTERN = 761 /^([A-Za-z]{3,9})\.?\s+(\d{1,2})(?:st|nd|rd|th)?\s*(?:[-\u2013\u2014]|to)\s*(?:[A-Za-z]{3,9}\.?\s+)?\d{1,2}(?:st|nd|rd|th)?(?:,?\s*(\d{4}))?$/i; 762 const ORDINAL_SUFFIX_PATTERN = /(\d{1,2})(?:st|nd|rd|th)\b/gi; 763 764 class GritTableController { 765 constructor(container) { 766 this.container = container; 767 this.table = container.querySelector("table"); 768 this.tbody = this.table?.querySelector("tbody"); 769 this.thead = this.table?.querySelector("thead"); 770 this.searchInput = container.querySelector( 771 '[data-grit-role="search-input"]' 772 ); 773 this.searchButton = container.querySelector( 774 '[data-grit-role="search-button"]' 775 ); 776 this.paginationRoot = container.querySelector( 777 '[data-grit-role="pagination"]' 778 ); 779 780 if (!this.table || !this.tbody) { 781 console.warn("GritTable: Missing table markup", container); 782 this.isReady = false; 783 return; 784 } 785 786 this.config = this._parseConfig(container.dataset); 787 this.state = { 788 search: this.searchInput?.value.trim() || "", 789 sortKey: null, 790 sortDirection: null, 791 page: this.config.initialPage, 792 }; 793 this.rowCache = []; 794 this.sortableHeaders = []; 795 this.isReady = true; 796 797 this._init(); 798 } 799 800 static initAll(root = document) { 801 Array.from(root.querySelectorAll(`[${DATA_ATTR}
801]`)).forEach((el) => 802 this.initElement(el) 803 ); 804 } 805 806 static initElement(container) { 807 if (!container || container._gritTableInstance) 808 return container?._gritTableInstance; 809 const controller = new GritTableController(container); 810 if (!controller.isReady) return null; 811 container._gritTableInstance = controller; 812 return controller; 813 } 814 815 destroy() { 816 if (!this.isReady) return; 817 this.table.removeEventListener("click", this._handleHeaderClick); 818 this.paginationRoot?.removeEventListener( 819 "click", 820 this._handlePaginationClick 821 ); 822 this.searchInput?.removeEventListener( 823 "keydown", 824 this._handleSearchKeydown 825 ); 826 this.searchButton?.removeEventListener("click", this._handleSearchSubmit); 827 delete this.container._gritTableInstance; 828 } 829 830 refresh() { 831 if (!this.isReady) return; 832 this._captureClientRows(); 833 this._decorateHeaders(); 834 if (this.config.filter === "client" || this.config.sort === "client") { 835 this._renderClientState(); 836 } 837 } 838 839 _init() { 840 this._captureClientRows(); 841 this._decorateHeaders(); 842 this._applyDefaultSort(); 843 this._bindEvents(); 844 if (this.config.pagination === "server") { 845 this._renderPagination({ 846 page: this.state.page, 847 totalPages: 848 parseInt(this.container.dataset.gritTotalPages || "1", 10) || 1, 849 }); 850 } 851 if (this.config.filter === "client" || this.config.sort === "client") { 852 this._renderClientState(); 853 } 854 } 855 856 _parseConfig(dataset) { 857 return { 858 filter: this._normalizeMode(dataset.gritFilter, DEFAULTS.filter), 859 sort: this._normalizeMode(dataset.gritSort, DEFAULTS.sort), 860 pagination: this._normalizeMode( 861 dataset.gritPagination, 862 DEFAULTS.pagination 863 ), 864 endpoint: dataset.gritEndpoint || "", 865 pageSize: this._toNumber(dataset.gritPageSize, DEFAULTS.pageSize), 866 initialPage: this._toNumber(dataset.gritPage, DEFAULTS.initialPage), 867 }; 868 } 869 870 _normalizeMode(value, fallback) { 871 if (!value) return fallback; 872 const normalized = value.toLowerCase(); 873 return MODES.all.has(normalized) ? normalized : fallback; 874 } 875 876 _toNumber(value, fallback) { 877 if (value == null || value === "") return fallback; 878 const parsed = parseInt(value, 10); 879 return Number.isNaN(parsed) ? fallback : parsed; 880 } 881 882 _captureClientRows() { 883 this.rowCache = Array.from(this.tbody.querySelectorAll("tr")).map( 884 (row) => ({ 885 html: row.outerHTML, 886 searchText: (row.textContent || "").toLowerCase(), 887 cells: Array.from(row.cells).map((cell) => 888 (cell.textContent || "").trim() 889 ), 890 }) 891 ); 892 } 893 894 _decorateHeaders() { 895 if (!this.thead) return; 896 this.sortableHeaders = Array.from( 897 this.thead.querySelectorAll("[data-grit-sortable]") 898 ); 899 this.sortableHeaders.forEach((header, index) => { 900 if (!header.dataset.gritSortKey) { 901 header.dataset.gritSortKey = 902 header.textContent?.trim().toLowerCase().replace(/\s+/g, "-") || 903 `col-${index}`; 904 } 905 header.dataset.gritSortIndex = 906 header.dataset.gritSortIndex || String(header.cellIndex ?? index); 907 header.removeAttribute("data-grit-sort-state"); 908 header.removeAttribute("aria-sort"); 909 }); 910 } 911 912 _applyDefaultSort() { 913 if (this.state.sortKey) return; 914 915 const direction = this.container.dataset.gritSortDefaultDirection; 916 const columnIndex = Number(this.container.dataset.gritSortDefaultColumn); 917 if (!SORT_DIRS.includes(direction) || Number.isNaN(columnIndex)) return; 918 919 const header = this.sortableHeaders.find( 920 (h) => Number(h.dataset.gritSortIndex) === columnIndex 921 ); 922 if (!header) return; 923 924 this.state.sortKey = header.dataset.gritSortKey; 925 this.state.sortDirection = direction; 926 this._updateHeaderStates(header, direction); 927 } 928 929 _bindEvents() { 930 this._handleHeaderClick = (e) => { 931 const header = e.target.closest("[data-grit-sortable]"); 932 if (header && this.table.contains(header)) { 933 e.preventDefault(); 934 this._toggleSort(header); 935 } 936 }; 937 938 this._handleSearchKeydown = (e) => { 939 if (e.key === "Enter") { 940 e.preventDefault(); 941 this._handleSearchSubmit(); 942 } 943 }; 944 945 this._handleSearchSubmit = () => { 946 const term = this.searchInput?.value.trim() || ""; 947 this.state.search = term; 948 if (MODES.client.has(this.config.filter)) { 949 this._renderClientState(); 950 } else if (MODES.server.has(this.config.filter)) { 951 this._requestFromServer({ search: term, page: 1 }); 952 } 953 }; 954 955 this._handlePaginationClick = (e) => { 956 const button = e.target.closest("[data-grit-page]"); 957 if (!button || button.disabled) return; 958 const targetPage = parseInt(button.dataset.gritPage, 10); 959 if (Number.isNaN(targetPage) || targetPage === this.state.page) return; 960 e.preventDefault(); 961 if (!MODES.server.has(this.config.pagination)) { 962 console.warn( 963 "GritTable: Pagination is only available in server mode." 964 ); 965 return; 966 } 967 this.state.page = targetPage; 968 this._requestFromServer({ page: targetPage }); 969 }; 970 971 this.table.addEventListener("click", this._handleHeaderClick); 972 this.paginationRoot?.addEventListener( 973 "click", 974 this._handlePaginationClick 975 ); 976 this.searchInput?.addEventListener("keydown", this._handleSearchKeydown); 977 this.searchButton?.addEventListener("click", this._handleSearchSubmit); 978 } 979 980 _toggleSort(header) { 981 const sortKey = header.dataset.gritSortKey; 982 if (!sortKey) return; 983 const nextDirection = this._getNextSortDirection(sortKey); 984 this.state.sortKey = nextDirection ? sortKey : null; 985 this.state.sortDirection = nextDirection; 986 this._updateHeaderStates(header, nextDirection); 987 988 if (MODES.client.has(this.config.sort)) { 989 this._renderClientState(); 990 } else if (MODES.server.has(this.config.sort)) { 991 this._requestFromServer({ 992 sort: this.state.sortKey, 993 dir: this.state.sortDirection, 994 page: this.state.page, 995 }); 996 } 997 } 998 999 _getNextSortDirection(sortKey) { 1000 if (this.state.sortKey !== sortKey) return SORT_DIRS[0]; 1001 if (this.state.sortDirection === SORT_DIRS[0]) return SORT_DIRS[1]; 1002 if (this.state.sortDirection === SORT_DIRS[1]) return null; 1003 return SORT_DIRS[0]; 1004 } 1005 1006 _updateHeaderStates(activeHeader, direction) {
1007 this.sortableHeaders.forEach((h) => { 1008 h.removeAttribute("data-grit-sort-state"); 1009 h.removeAttribute("aria-sort"); 1010 }); 1011 1012 if (activeHeader && direction) { 1013 activeHeader.dataset.gritSortState = direction; 1014 activeHeader.setAttribute( 1015 "aria-sort", 1016 direction === "asc" ? "ascending" : "descending" 1017 ); 1018 } 1019 } 1020 1021 _renderClientState() { 1022 let rows = this.rowCache.slice(); 1023 1024 if (MODES.client.has(this.config.filter) && this.state.search) { 1025 const term = this.state.search.toLowerCase(); 1026 rows = rows.filter((row) => row.searchText.includes(term)); 1027 } 1028 1029 if ( 1030 MODES.client.has(this.config.sort) && 1031 this.state.sortKey && 1032 this.state.sortDirection 1033 ) { 1034 rows = this._sortRows( 1035 rows, 1036 this.state.sortKey, 1037 this.state.sortDirection 1038 ); 1039 } 1040 1041 this.tbody.innerHTML = rows.map((row) => row.html).join(""); 1042 } 1043 1044 _sortRows(rows, sortKey, direction) { 1045 const header = this.sortableHeaders.find( 1046 (h) => h.dataset.gritSortKey === sortKey 1047 ); 1048 const columnIndex = header 1049 ? parseInt(header.dataset.gritSortIndex || "0", 10) 1050 : 0; 1051 const multiplier = direction === "desc" ? -1 : 1; 1052 const collator = Intl.Collator 1053 ? new Intl.Collator(undefined, { numeric: true, sensitivity: "base" }) 1054 : null; 1055 const isDateColumn = this._isDateColumn(rows, columnIndex); 1056 1057 return rows.slice().sort((a, b) => { 1058 const aVal = a.cells[columnIndex] || ""; 1059 const bVal = b.cells[columnIndex] || ""; 1060 1061 if (isDateColumn) { 1062 const aIsEmpty = aVal === ""; 1063 const bIsEmpty = bVal === ""; 1064 if (aIsEmpty || bIsEmpty) { 1065 if (aIsEmpty && bIsEmpty) return 0; 1066 return aIsEmpty ? 1 : -1; 1067 } 1068 return ( 1069 (this._parseDate(aVal).valueOf() - this._parseDate(bVal).valueOf()) * 1070 multiplier 1071 ); 1072 } 1073 1074 return ( 1075 (collator ? collator.compare(aVal, bVal) : aVal.localeCompare(bVal)) * 1076 multiplier 1077 ); 1078 }); 1079 } 1080 1081 _isDateColumn(rows, columnIndex) { 1082 if (typeof window.moment !== "function") return false; 1083 1084 const values = rows 1085 .map((row) => (row.cells[columnIndex] || "").trim()) 1086 .filter((value) => value !== ""); 1087 1088 if (!values.length) return false; 1089 1090 return values.every((value) => this._parseDate(value).isValid()); 1091 } 1092 1093 _parseDate(value) { 1094 return window.moment(this._normalizeIfDateRange(value), DATE_FORMATS, true); 1095 } 1096 1097 _normalizeIfDateRange(value) { 1098 const rangeMatch = value.match(DATE_RANGE_PATTERN); 1099 if (rangeMatch) { 1100 const [, month, day, year] = rangeMatch; 1101 return year ? `${month} ${day}, ${year}` : `${month} ${day}`; 1102 } 1103 1104 // replace any ordinal suffixes with the numeric day 1105 return value.replace(ORDINAL_SUFFIX_PATTERN, "$1"); 1106 } 1107 1108 _requestFromServer(overrides = {}) { 1109 if (!this.config.endpoint) { 1110 console.warn( 1111 "GritTable: Server endpoint missing (data-grit-endpoint)." 1112 ); 1113 return; 1114 } 1115 1116 if (overrides.page) this.state.page = overrides.page; 1117 1118 const params = { 1119 search: overrides.search ?? this.state.search, 1120 sort: overrides.sort ?? this.state.sortKey, 1121 dir: overrides.dir ?? this.state.sortDirection, 1122 page: overrides.page || this.state.page || 1, 1123 pageSize: overrides.pageSize || this.config.pageSize, 1124 }; 1125 1126 const queryString = this._buildQueryString(params); 1127 const url = `${this.config.endpoint}${ 1128 queryString 1129 ? (this.config.endpoint.includes("?") ? "&" : "?") + queryString 1130 : "" 1131 }`; 1132 1133 this._setLoading(true); 1134 1135 fetch(url, { 1136 headers: { "X-Requested-With": "XMLHttpRequest" }, 1137 credentials: "same-origin", 1138 }) 1139 .then((res) => 1140 res.ok 1141 ? res.json() 1142 : Promise.reject( 1143 new Error(`GritTable request failed: ${res.status}`) 1144 ) 1145 ) 1146 .then((payload) => this._applyServerResponse(payload)) 1147 .catch((err) => console.error("GritTable: Server request failed", err)) 1148 .finally(() =>
1148 this._setLoading(false)); 1149 } 1150 1151 _applyServerResponse(payload) { 1152 if (!payload) return; 1153 1154 if (payload.theadHtml && this.thead) { 1155 this.thead.innerHTML = payload.theadHtml; 1156 this._decorateHeaders(); 1157 } 1158 1159 if (payload.rowsHtml) { 1160 this.tbody.innerHTML = payload.rowsHtml; 1161 } else if (Array.isArray(payload.rows)) { 1162 this.tbody.innerHTML = payload.rows.join(""); 1163 } else if (payload.tableHtml) { 1164 this.table.outerHTML = payload.tableHtml; 1165 this.table = this.container.querySelector("table"); 1166 if (this.table) { 1167 this.tbody = this.table.querySelector("tbody"); 1168 this.thead = this.table.querySelector("thead"); 1169 this.table.addEventListener("click", this._handleHeaderClick); 1170 this._decorateHeaders(); 1171 } 1172 } 1173 1174 if (payload.searchTerm !== undefined && this.searchInput) { 1175 this.searchInput.value = payload.searchTerm; 1176 this.state.search = payload.searchTerm; 1177 } 1178 1179 if (payload.sort) { 1180 this.state.sortKey = payload.sort.key || this.state.sortKey; 1181 this.state.sortDirection = 1182 payload.sort.direction || this.state.sortDirection; 1183 const header = this.sortableHeaders.find( 1184 (h) => h.dataset.gritSortKey === this.state.sortKey 1185 ); 1186 if (header) this._updateHeaderStates(header, this.state.sortDirection); 1187 } 1188 1189 if (payload.pagination) { 1190 this.state.page = payload.pagination.page || 1; 1191 this._renderPagination(payload.pagination); 1192 } else if (this.paginationRoot) { 1193 this._renderPagination(null); 1194 } 1195 1196 if ( 1197 MODES.client.has(this.config.filter) || 1198 MODES.client.has(this.config.sort) 1199 ) { 1200 this._captureClientRows(); 1201 } 1202 } 1203 1204 _renderPagination(pagination) { 1205 if (!this.paginationRoot) return; 1206 if (!pagination || pagination.totalPages <= 1) { 1207 this.paginationRoot.innerHTML = ""; 1208 this.paginationRoot.classList.add(CLASSES.hidden); 1209 return; 1210 } 1211 1212 this.paginationRoot.classList.remove(CLASSES.hidden); 1213 const current = pagination.page || 1; 1214 const totalPages = pagination.totalPages || 1; 1215 const fragment = document.createDocumentFragment(); 1216 1217 fragment.appendChild( 1218 this._createPageButton( 1219 "<", 1220 Math.max(1, current - 1), 1221 current === 1, 1222 "Previous page" 1223 ) 1224 ); 1225 1226 const delta = 2; 1227 const start = Math.max(1, current - delta); 1228 const end = Math.min(totalPages, current + delta); 1229 for (let page = start; page <= end; page++) { 1230 fragment.appendChild( 1231 this._createPageButton(String(page), page, page === current) 1232 ); 1233 } 1234 1235 fragment.appendChild( 1236 this._createPageButton( 1237 ">", 1238 Math.min(totalPages, current + 1), 1239 current === totalPages, 1240 "Next page" 1241 ) 1242 ); 1243 1244 this.paginationRoot.innerHTML = ""; 1245 this.paginationRoot.appendChild(fragment); 1246 } 1247 1248 _createPageButton(label, page, disabled, ariaLabel) { 1249 const button = document.createElement("button"); 1250 button.type = "button"; 1251 button.className = `grit-icon-button primary sm${ 1252 disabled ? " active" : "" 1253 }`; 1254 button.dataset.gritPage = String(page); 1255 button.disabled = Boolean(disabled); 1256 if (ariaLabel) button.setAttribute("aria-label", ariaLabel); 1257 button.innerHTML = `<span>${label}</span>`; 1258 return button; 1259 } 1260 1261 _setLoading(isLoading) { 1262 this.container.classList.toggle(CLASSES.loading, Boolean(isLoading)); 1263 } 1264 1265 _buildQueryString(params) { 1266 const entries = Object.entries(params).filter( 1267 ([, v]) => v != null && v !== "" 1268 ); 1269 if (!entries.length) return ""; 1270 if (typeof URLSearchParams !== "undefined") { 1271 const usp = new URLSearchParams(); 1272 entries.forEach(([k, v]) => usp.append(k, v)); 1273 return usp.toString(); 1274 } 1275 return entries 1276 .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`) 1277 .join("&"); 1278 } 1279 } 1280 1281 function autoInitialize() { 1282 GritTableController.initAll(document); 1283 } 1284 1285 if (document.readyState === "loading") { 1286 document.addEventListener("DOMContentLoaded", autoInitialize); 1287 } else { 1288 autoInitialize(); 1289 } 1290 1291 window.GritTable = window.GritTable || {}; 1292 window.GritTable.Controller = GritTableController; 1293 window.GritTable.init = (root) => 1294 GritTableController.initAll(root || document); 1295 window.GritTable.initElement = (element) => 1296 GritTableController.initElement(element); 1297})(window, document); 1298 1299 1300; 1301////pf: javascript/smp-expandable-sections.js 1302$(function () { 1303 $(".expandable-sections > section > .container") 1304 .slice(1) 1305 .each(function () { 1306 const $container = $(this); 1307 const $h1 = $container.find("> h1"); 1308 if ($h1.length) { 1309 const $toggle = $( 1310 "<a class='section-expand'><i class='fa fa-chevron-right'></i><i class='fa fa-chevron-down'></i></a>" 1311 ); 1312 const $section = $container.closest("section"); 1313 const h1Index = $container.find("> *").index($h1); 1314 $container 1315 .find("> *:gt(" + h1Index + ")") 1316 .addClass("section-expand-hidden"); 1317 $h1.eq(0).css("display", "").append($toggle); 1318 $section.addClass("section-expand"); 1319 } 1320 });
1321 1322 $(document).on("click", ".section-expand", function () { 1323 if ($(this).is("section") && !$(this).hasClass("expanded")) { 1324 $(this).addClass("expanded"); 1325 return false; 1326 } 1327 }); 1328 1329 $(document).on( 1330 "click", 1331 ".section-expand.expanded a.section-expand", 1332 function () { 1333 var $section = $(this).closest("section.section-expand"); 1334 if ($section.hasClass("expanded")) { 1335 $section.removeClass("expanded"); 1336 return false; 1337 } 1338 } 1339 ); 1340 1341 const initExpandos = function () { 1342 const expandoHeaders = document.querySelectorAll(".smp-expando-header"); 1343 expandoHeaders.forEach((header) => { 1344 const expando = header.closest(".smp-expando"); 1345 1346 if (expando.closest('.ck-editor, .ck-content')) { 1347 // Skip if inside a CKEditor 1348 return; 1349 } 1350 1351 const description = expando.querySelector(".smp-expando-description"); 1352 1353 const noInitClass = 1354 !expando.classList.contains("collapsed") && 1355 !expando.classList.contains("expanded"); 1356 if (noInitClass) { 1357 expando.classList.add("collapsed"); 1358 } 1359 1360 if (expando.classList.contains("collapsed")) { 1361 description.style.height = "0px"; 1362 description.style.overflow = "hidden"; 1363 } else { 1364 description.style.height = "auto"; 1365 } 1366 1367 header.addEventListener("click", function () { 1368 if (expando.classList.contains("expanded")) { 1369 const height = description.scrollHeight; 1370 description.style.height = height + "px"; 1371 1372 description.offsetHeight; 1373 1374 description.style.height = "0px"; 1375 expando.classList.remove("expanded"); 1376 expando.classList.add("collapsed"); 1377 } else { 1378 expando.classList.remove("collapsed"); 1379 expando.classList.add("expanded"); 1380 1381 const height = description.scrollHeight; 1382 description.style.height = height + "px"; 1383 1384 description.addEventListener("transitionend", function handler() { 1385 description.style.height = "auto"; 1386 description.removeEventListener("transitionend", handler); 1387 }); 1388 } 1389 }); 1390 }); 1391 }; 1392 1393 initExpandos(); 1394 window.addEventListener("initExpandos", initExpandos); 1395 1396 const legacyExpandos = Array.from( 1397 document.querySelectorAll(".smp-expando") 1398 ).filter((expando) => expando.querySelector("h1.smp-expando-title")); 1399 legacyExpandos.forEach((expando) => { 1400 const title = expando.querySelector("h1.smp-expando-title"); 1401 const description = expando.querySelector(".smp-expando-description"); 1402 const toggle = expando.querySelector(".smp-expando-toggle"); 1403 1404 const noInitClass = 1405 !expando.classList.contains("collapsed") && 1406 !expando.classList.contains("expanded"); 1407 if (noInitClass) { 1408 expando.classList.add("collapsed"); 1409 } 1410 1411 if (expando.classList.contains("collapsed")) { 1412 description.style.height = "0px"; 1413 description.style.overflow = "hidden"; 1414 } 1415 1416 const handleToggle = function (e) { 1417 e.preventDefault(); 1418 e.stopPropagation(); 1419 1420 if (expando.classList.contains("expanded")) { 1421 const height = description.scrollHeight; 1422 description.style.height = height + "px"; 1423 1424 description.offsetHeight; 1425 1426 description.style.height = "0px"; 1427 expando.classList.remove("expanded"); 1428 expando.classList.add("collapsed"); 1429 } else { 1430 expando.classList.remove("collapsed"); 1431 expando.classList.add("expanded"); 1432 1433 const height = description.scrollHeight; 1434 description.style.height = height + "px"; 1435 1436 description.addEventListener("transitionend", function handler() { 1437 description.style.height = "auto"; 1438 description.removeEventListener("transitionend", handler); 1439 }); 1440 } 1441 }; 1442 1443 if (toggle) { 1444 toggle.addEventListener("click", handleToggle); 1445 } 1446 1447 if (title) { 1448 title.style.cursor = "pointer"; 1449 title.addEventListener("click", handleToggle); 1450 } 1451 }); 1452}); 1453 1454 1455; 1456////pf: javascript/modal.js 1457; 1458(function ($) { 1459 1460 $.fn.modalFrame = function (options) { 1461 $(this).each(function () { 1462 const $self = $(this); 1463 const settings = $.extend({ 1464 defaultW: '80vw', 1465 defaultH: '80vh' 1466 }, options); 1467 1468 const $frame = $('<div class="smp-modal"><button type="button" smp-modal-close><i class="fa fa-times"></i></button><iframe /></div>'); 1469 1470 $frame.find('button').on('click', function () { 1471 $frame.detach(); 1472 }); 1473 1474 $(this).on('click', function () { 1475 $frame.find("iframe").attr({ 1476 src: settings.src || $self.attr('smp-frame-src') || $self.attr('smp-modal-frame'), 1477 style: ("height: " + ($self.attr('smp-frame-height') || settings.defaultH)) 1478 + (";
1478width:" + ($self.attr('smp-frame-width') || settings.defaultW)) 1479 }); 1480 $('body').append($frame.css('display', 'block')); 1481 return false; 1482 }); 1483 }); 1484 1485 return this; 1486 }; 1487 1488 $.fn.modalFrame.open = function (options) { 1489 if (!options.src) { 1490 return; 1491 } 1492 1493 const settings = $.extend({ 1494 defaultW: '80vw', 1495 defaultH: '80vh' 1496 }, options); 1497 1498 const $frame = $('<div class="smp-modal"><button type="button" smp-modal-close><i class="fa fa-times"></i></button><iframe /></div>'); 1499 1500 $frame.find('button').on('click', function () { 1501 $frame.detach(); 1502 $('body').removeClass('modal-open'); 1503 }); 1504 1505 $frame.find("iframe").attr({ 1506 src: options.src, 1507 style: "height: " + settings.defaultH + ";width:" + settings.defaultW 1508 }); 1509 1510 $('body').append($frame.css('display', 'block')).addClass('modal-open'); 1511 return false; 1512 }; 1513 1514 $.fn.modalFrame.close = function () { 1515 $('.smp-modal:visible').detach(); 1516 $('body').removeClass('modal-open'); 1517 }; 1518 1519 $(function () { 1520 const settings = { 1521 defaultW: '80vw', 1522 defaultH: '80vh' 1523 }; 1524 1525 $(document).on('click', '[smp-frame-src], [smp-modal-frame]', function () { 1526 const $self = $(this); 1527 1528 $.fn.modalFrame.open({ 1529 src: $self.attr('smp-frame-src') || $self.attr('smp-modal-frame'), 1530 style: ("height: " + ($self.attr('smp-frame-height') || settings.defaultH)) 1531 + (";width:" + ($self.attr('smp-frame-width') || settings.defaultW)) 1532 }); 1533 }); 1534 }); 1535 1536 $.fn.modalElement = function (options) { 1537 $(this).each(function () { 1538 const $self = $(this); 1539 const $target = $((options && options.target) || $self.attr('smp-modal-selector')); 1540 1541 if (!$target.closest('.smp-modal').length) { 1542 $target.wrap('<div class="smp-modal"><div class="smp-modal-element"></div></div>'); 1543 } 1544 1545 $target.css('display', 'block'); 1546 const $modal = $target.parent().parent(); 1547 1548 if (!$modal.find('[smp-modal-close]').length) { 1549 $modal.find('.smp-modal-element').prepend('<button smp-modal-close type="button"><i class="fa fa-times"></i></button>'); 1550 1551 $modal.find('[smp-modal-close]').on('click', function () { 1552 $modal.css('display', 'none'); 1553 $('body').removeClass('modal-open'); 1554 return false; 1555 }); 1556 } 1557 1558 if ($self.attr('smp-modal-selector')) { 1559 $(document).on('click', `[smp-modal-selector=${$self.attr('smp-modal-selector')}]`, function () { 1560 $modal.css('display', 'block'); 1561 return false; 1562 }); 1563 } 1564 else { 1565 $self.on('click', function () { 1566 $modal.css('display', 'block'); 1567 return false; 1568 }); 1569 } 1570 }); 1571 1572 return this; 1573 }; 1574 1575 $.fn.modalElement.open = function (options) { 1576 let $target = null; 1577 1578 try { 1579 $target = options && options.content && $(options.content) 1580 || options && options.target && $(options.target) 1581 || $(this).attr('smp-modal-selector'); 1582 } 1583 catch (err) { 1584 console.warn('Is your target invalid or is the content not valid HTML wrapped in a tag?', err); 1585 return; 1586 } 1587 1588 if (!$target) { 1589 console.warn('No modal target'); 1590 return; 1591 } 1592 1593 if (!$target.closest('.smp-modal').length) { 1594 $target.wrap('<div class="smp-modal"><div class="smp-modal-element"></div></div>'); 1595 } 1596 1597 function handleClose() { 1598 if (!options.content) { 1599 $modal.css('display', 'none'); 1600 $('body').removeClass('modal-open'); 1601 } else { 1602 setTimeout(() => { 1603 $modal.remove(); 1604 1605 if ($('.smp-modal:visible').length === 0) { 1606 $('body').removeClass('modal-open'); 1607 } 1608 }, 0); 1609 } 1610 return false; 1611 } 1612 1613 $target.css('display', 'block'); 1614 const $modal = $target.parent().parent(); 1615 1616 if (!$modal.find('[smp-modal-close]').length) { 1617 $modal.find('.smp-modal-element').prepend('<button smp-modal-close type="button"><i class="fa fa-times"></i></button>'); 1618 1619 $modal.find('[smp-modal-close]').on('click', handleClose); 1620 } 1621 1622 const existingSubmitBtn = $modal.find('[smp-modal-submit]').length; 1623 if (options.onSubmit && !existingSubmitBtn) { 1624 const $submitBtn = $(`<button smp-modal-submit type="button" class="grit-button contained primary">${options.submitText ?? 'Submit'}</button>`); 1625 const $cancelBtn = $(`<button type="button" class="grit-button outlined secondary">${options.cancelText ?? 'Cancel'}</button>`); 1626 $submitBtn.on('click', options.onSubmit); 1627 $cancelBtn.on('click', handleClose);
1628 const $buttonContainer = $('<div class="f-row align-center justify-end gap-xs wrap"></div>'); 1629 $buttonContainer.append($cancelBtn); 1630 $buttonContainer.append($submitBtn); 1631 $modal.find('.smp-modal-element').append($buttonContainer); 1632 } 1633 1634 $modal.css({ display: 'block' }); 1635 1636 if (options.content) { 1637 $modal.addClass('smp-modal-set-from-content', true); 1638 $('body').append($modal); 1639 } 1640 1641 $('body').addClass('modal-open'); 1642 }; 1643 1644 $.fn.modalElement.close = function () { 1645 $('.smp-modal').each(function () { 1646 var $modal = $(this); 1647 if (!$modal.hasClass('smp-modal-set-from-content')) { 1648 $modal.css('display', 'none'); 1649 1650 if ($('.smp-modal:visible').length === 0) { 1651 $('body').removeClass('modal-open'); 1652 } 1653 } else { 1654 setTimeout(() => { 1655 $modal.remove(); 1656 1657 if ($('.smp-modal:visible').length === 0) { 1658 $('body').removeClass('modal-open'); 1659 } 1660 }, 0); 1661 } 1662 }); 1663 1664 $('body').removeClass('modal-open'); 1665 }; 1666 1667 $.fn.modalConfirm = function () {}; 1668 1669 $.fn.modalConfirm.open = function (options) { 1670 const content = options.content || 'Are you sure?'; 1671 const title = options.title || 'Confirmation'; 1672 1673 let $modal = $( 1674 `<section class="smp-modal confirm ${options.cssClass}" style="display: block;"> 1675 <div class="smp-modal-element"> 1676 <h2>${title}</h2> 1677 ${content} 1678 <ul class='input-rows'> 1679 <li class='action-row'> 1680 <button type="button" class="BackButton" smp-modal-confirm-cancel>No</button> 1681 <button type="button" class="ForwardButton" smp-modal-confirm-confirm>Yes</button> 1682 </li> 1683 </div> 1684 </div> 1685 </section>`); 1686 1687 $modal.find('[smp-modal-confirm-confirm]').on('click', function () { 1688 $modal.remove(); 1689 1690 if ($('.smp-modal:visible').length === 0) { 1691 $('body').removeClass('modal-open'); 1692 } 1693 if (options.confirm) { 1694 options.confirm(); 1695 } 1696 }); 1697 1698 $modal.find('[smp-modal-confirm-cancel]').on('click', function () { 1699 $modal.remove(); 1700 1701 if ($('.smp-modal:visible').length === 0) { 1702 $('body').removeClass('modal-open'); 1703 } 1704 if (options.cancel) { 1705 options.cancel(); 1706 } 1707 }); 1708 1709 $('body').append($modal).addClass('modal-open'); 1710 }; 1711 1712 $.fn.modalAlert = function () { }; 1713 1714 $.fn.modalAlert.close = function (options) { 1715 $('.smp-modal:visible').detach(); 1716 $('body').removeClass('modal-open'); 1717 }; 1718 1719 $.fn.modalAlert.open = function (options) { 1720 const content = options.content || ''; 1721 const title = options.title || 'Alert'; 1722 1723 let $modal = $( 1724 `<section class="smp-modal alert" style="display: block;"> 1725 <div class="smp-modal-element"> 1726 <h2>${title}</h2> 1727 ${content} 1728 <ul class='input-rows'> 1729 <li class='action-row'> 1730 <button type="button" class="ForwardButton" smp-modal-confirm-confirm>OK</button> 1731 </li> 1732 </ul> 1733 </div> 1734 </section>`); 1735 1736 $modal.find('[smp-modal-confirm-confirm]').on('click', function () { 1737 $modal.remove(); 1738 1739 if ($('.smp-modal:visible').length === 0) { 1740 $('body').removeClass('modal-open'); 1741 } 1742 }); 1743 1744 $('body').append($modal).addClass('modal-open'); 1745 }; 1746 1747 $(function () { 1748 $('[smp-modal-close]').on('click', function () { 1749 $(this).closest('.smp-modal').css('display', 'none'); 1750 $('body').removeClass('modal-open'); 1751 return false; 1752 }); 1753 1754 $(document).on('click', function (e) { 1755 const $target = $(e.target); 1756 if ($target.hasClass('smp-modal') && $target.find('[smp-modal-close]').length > 0) { 1757 $target.css('display', 'none'); 1758 $('body').removeClass('modal-open'); 1759 return false; 1760 } 1761 }); 1762 1763 $(document).on('keydown', function (e) { 1764 if (e.key === 'Escape') { 1765 $('.smp-modal:not([react-managed])').css('display', 'none'); 1766 $('body').removeClass('modal-open'); 1767 return false; 1768 } 1769 }); 1770 1771 setTimeout(() => $('[smp-modal-selector]').modalElement(), 100); 1772 });
1773 1774})(jQuery); 1775 1776 1777; 1778////pf: javascript/duplicate-user-check.js 1779(function () { 1780 if (typeof window.SMP === 'undefined') { 1781 window.SMP = {}; 1782 } 1783 1784 function buildQuery(params) { 1785 var pieces = []; 1786 Object.keys(params || {}).forEach(function (key) { 1787 var value = params[key]; 1788 if (value === null || value === undefined) return; 1789 var str = String(value).trim(); 1790 if (!str) return; 1791 pieces.push(encodeURIComponent(key) + '=' + encodeURIComponent(str)); 1792 }); 1793 return pieces.join('&'); 1794 } 1795 1796 function htmlEscape(value) { 1797 if (value === null || value === undefined) return ''; 1798 return String(value) 1799 .replace(/&/g, '&') 1800 .replace(/</g, '<') 1801 .replace(/>/g, '>') 1802 .replace(/"/g, '"') 1803 .replace(/'/g, '''); 1804 } 1805 1806 function formatPhoneDigits(value) { 1807 if (!value) return ''; 1808 return String(value).replace(/\D/g, ''); 1809 } 1810 1811 function restoreHideOnClickButton(btn) { 1812 if (!btn) return; 1813 var $b = btn.jquery ? btn : $(btn); 1814 if (!$b.length) return; 1815 var original = $b.data('original-content'); 1816 if (original) { 1817 $b.html(original); 1818 $b.removeData('original-content'); 1819 } 1820 $b.removeClass('disabled'); 1821 $b.find('.fa-spinner').remove(); 1822 } 1823 1824 function formatPhoneDisplay(value) { 1825 if (!value) return ''; 1826 var digits = formatPhoneDigits(value); 1827 if (digits.length === 10) { 1828 return '(' + digits.substr(0, 3) + ') ' + digits.substr(3, 3) + '-' + digits.substr(6); 1829 } 1830 if (digits.length === 11 && digits.charAt(0) === '1') { 1831 return '1 (' + digits.substr(1, 3) + ') ' + digits.substr(4, 3) + '-' + digits.substr(7); 1832 } 1833 return String(value); 1834 } 1835 1836 function initials(first, last) { 1837 var a = (first || '').trim().charAt(0); 1838 var b = (last || '').trim().charAt(0); 1839 return (a + b).toUpperCase() || '?'; 1840 } 1841 1842 function getHeaderText(response) { 1843 var total = (response && response.matches ? response.matches.length : 0) || 0; 1844 var bits = []; 1845 if (response && response.matchedName) bits.push('NAME'); 1846 if (response && response.matchedEmail) bits.push('EMAIL'); 1847 if (response && response.matchedPhone) bits.push('PHONE'); 1848 var suffix = bits.length ? bits.join('/') : 'DETAILS'; 1849 var userLabel = total === 1 ? 'USER' : 'USERS'; 1850 return total + ' ' + userLabel + ' FOUND WITH THAT ' + suffix; 1851 } 1852 1853 window.SMP.checkForDuplicateUser = function (criteria) { 1854 var qs = buildQuery({ 1855 firstName: criteria && criteria.firstName, 1856 lastName: criteria && criteria.lastName, 1857 email: criteria && criteria.email, 1858 phone: formatPhoneDigits(criteria && criteria.phone) 1859 }); 1860 1861 if (!qs) { 1862 return Promise.resolve({ matches: [], totalCount: 0 }); 1863 } 1864 1865 return fetch('/api/profile/duplicate-search?' + qs, { 1866 headers: { 'Content-Type': 'application/json' }, 1867 method: 'GET', 1868 credentials: 'same-origin' 1869 }) 1870 .then(function (res) { 1871 if (!res.ok) { 1872 console.warn('duplicate-search returned ' + res.status); 1873 return { matches: [], totalCount: 0 }; 1874 } 1875 return res.json(); 1876 }) 1877 .catch(function (err) { 1878 console.warn('duplicate-search failed', err); 1879 return { matches: [], totalCount: 0 }; 1880 }); 1881 }; 1882 1883 window.SMP.openDuplicateUserModal = function (options) { 1884 var response = options && options.response; 1885 var matches = (response && response.matches) || options && options.matches || []; 1886 1887 if (!matches.length) { 1888 if (options && typeof options.onAddNew === 'function') { 1889 options.onAddNew(); 1890 } 1891 return; 1892 } 1893 1894 if (options && options.triggerButton) { 1895 restoreHideOnClickButton(options.triggerButton); 1896 } 1897
1898 var $existing = $('.smp-duplicate-user-modal').closest('.smp-modal'); 1899 if ($existing.length) { 1900 $existing.remove(); 1901 } 1902 1903 var headerText = getHeaderText(response || { matches: matches }); 1904 1905 var listHtml = matches.map(function (match) { 1906 var name = (match.nameFirst || '') + ' ' + (match.nameLast || ''); 1907 var matchedOn = (match.matchedOn || []); 1908 var tags = matchedOn.length 1909 ? 'Matches on: ' + matchedOn.map(htmlEscape).join(', ') 1910 : ''; 1911 var phoneDisplay = formatPhoneDisplay(match.phone); 1912 var detailParts = []; 1913 if (match.username && String(match.username).trim() !== '') { 1914 detailParts.push('<span class="smp-duplicate-user-username">' 1915 + '<span class="smp-duplicate-user-username-tag">Username:</span> ' 1916 + htmlEscape(match.username) 1917 + '</span>'); 1918 } 1919 if (phoneDisplay) { 1920 detailParts.push('<span class="smp-duplicate-user-phone">' 1921 + '<span class="smp-duplicate-user-phone-tag">Phone:</span> ' 1922 + htmlEscape(phoneDisplay) 1923 + '</span>'); 1924 } 1925 if (match.email && String(match.email).trim() !== '') { 1926 detailParts.push('<span class="smp-duplicate-user-email">' 1927 + '<span class="smp-duplicate-user-email-tag">Email:</span> ' 1928 + htmlEscape(match.email) 1929 + '</span>'); 1930 } 1931 var details = detailParts.join(' | '); 1932 1933 var avatar = '<span class="smp-duplicate-user-avatar">' 1934 + htmlEscape(initials(match.nameFirst, match.nameLast)) 1935 + '</span>'; 1936 1937 var expandedRows = [ 1938 { label: 'Name', value: name.trim() }, 1939 { label: 'Username', value: match.username }, 1940 { label: 'Email', value: match.email }, 1941 { label: 'Phone', value: phoneDisplay }, 1942 { label: 'Type', value: match.isGuardian ? 'Adult/Guardian' : 'Athlete' }, 1943 { label: 'User ID', value: match.userId }, 1944 { label: 'Profile ID', value: match.profileId } 1945 ] 1946 .filter(function (r) { return r.value && String(r.value).trim() !== ''; }) 1947 .map(function (r) { 1948 return '<div class="smp-duplicate-user-expanded-row">' 1949 + '<span class="smp-duplicate-user-expanded-label">' + htmlEscape(r.label) + ':</span> ' 1950 + '<span class="smp-duplicate-user-expanded-value">' + htmlEscape(r.value) + '</span>' 1951 + '</div>'; 1952 }).join(''); 1953 1954 var viewUrl = match.userId 1955 ? '/util/admin/users/user-details?UserId=' + encodeURIComponent(match.userId) 1956 : null; 1957 1958 var expanded = 1959 '<div class="smp-duplicate-user-expanded">' 1960 + expandedRows 1961 + (viewUrl 1962 ? '<div class="smp-duplicate-user-expanded-actions">' 1963 + '<a href="' + htmlEscape(viewUrl) + '" target="_blank" class="LinkButton">View Full Profile</a>' 1964 + '</div>' 1965 : '') 1966 + '</div>'; 1967 1968 return '<li data-profile-id="' + htmlEscape(match.profileId) + '">' 1969 + '<div class="smp-duplicate-user-row">' 1970 + avatar 1971 + '<span class="smp-duplicate-user-info">' 1972 + '<span class="smp-duplicate-user-name">' + htmlEscape(name.trim()) + '</span>' 1973 + (tags ? '<span class="smp-duplicate-user-tags">' + tags + '</span>' : '') 1974 + '<span class="smp-duplicate-user-details">' + details + '</span>' 1975 + '</span>' 1976 + '<span class="smp-duplicate-user-chevron"><i class="fa fa-chevron-right"></i></span>' 1977 + '</div>' 1978 + expanded 1979 + '</li>'; 1980 }).join(''); 1981 1982 var contentHtml =
1983 '<section class="smp-duplicate-user-modal">' 1984 + '<h1><i class="fa fa-exclamation-triangle smp-duplicate-user-warning"></i>' + htmlEscape(headerText) + '</h1>' 1985 + '<p class="smp-duplicate-user-intro">If one of the contacts below is the correct match, please select them. Otherwise, choose "Add New User".</p>' 1986 + '<ul class="smp-duplicate-user-list">' + listHtml + '</ul>' 1987 + '<div class="smp-duplicate-user-footer">' 1988 + '<button type="button" class="ForwardButton" data-smp-duplicate-add-new>+ Add New User</button>' 1989 + '</div>' 1990 + '</section>'; 1991 1992 var $content = $(contentHtml); 1993 1994 $content.find('ul.smp-duplicate-user-list li').each(function (index) { 1995 var match = matches[index]; 1996 if (match && match.resolvedImageFile) { 1997 $(this).find('.smp-duplicate-user-avatar') 1998 .empty() 1999 .css('background-image', 'url(' + JSON.stringify(match.resolvedImageFile) + ')'); 2000 } 2001 }); 2002 2003 $content.find('ul.smp-duplicate-user-list .smp-duplicate-user-row').on('click', function () { 2004 var $li = $(this).closest('li'); 2005 $li.toggleClass('is-expanded'); 2006 }); 2007 2008 $content.find('[data-smp-duplicate-add-new]').on('click', function () { 2009 $.fn.modalElement.close(); 2010 if (options && typeof options.onAddNew === 'function') { 2011 options.onAddNew(); 2012 } 2013 }); 2014 2015 $.fn.modalElement.open({ content: $content }); 2016 }; 2017 2018 window.SMP.runDuplicateUserPreCheck = function (criteria, handlers) { 2019 return window.SMP.checkForDuplicateUser(criteria).then(function (response) { 2020 var matches = (response && response.matches) || []; 2021 if (!matches.length) { 2022 if (handlers && typeof handlers.onAddNew === 'function') { 2023 handlers.onAddNew(); 2024 } 2025 return; 2026 } 2027 window.SMP.openDuplicateUserModal({ 2028 response: response, 2029 matches: matches, 2030 onAddNew: handlers && handlers.onAddNew, 2031 triggerButton: handlers && handlers.triggerButton 2032 }); 2033 }); 2034 }; 2035})(); 2036 2037 2038; 2039////pf: javascript/history-modal.js 2040(function (window, $) { 2041 2042 const hiddenKeys = /^(validfrom|validto|_timestamp|_isoriginal)$/i; 2043 2044 function formatLog(key, value) { 2045 if (key.match(/userid/gi)) { 2046 value = `<a href='/util/admin/users/users.aspx?ShowDeletedAccounts=true&ShowOtherBrandsAccounts=true&UserId=${value}'>${value}</a>` 2047 } 2048 2049 return `<span class='label'>${key}:</span> ${value}`; 2050 } 2051 2052 function parseUtcDate(value) { 2053 if (value instanceof Date) 2054 return value; 2055 2056 const text = String(value); 2057 if (/[zZ]|[+-]\d{2}:?\d{2}$/.test(text)) 2058 return new Date(text); 2059 2060 return new Date((text.indexOf('T') >= 0 ? text : text.replace(' ', 'T')) + 'Z'); 2061 } 2062 2063 function formatHeadingDate(value) { 2064 if (value == null || value === '') 2065 return ''; 2066 2067 const d = parseUtcDate(value); 2068 if (Number.isNaN(d.getTime()) || d.getUTCFullYear() >= 9999) 2069 return ''; 2070 2071 const hours24 = d.getHours(); 2072 const hours12 = hours24 % 12 || 12; 2073 const minutes = String(d.getMinutes()).padStart(2, '0'); 2074 const meridiem = hours24 < 12 ? 'AM' : 'PM'; 2075 return `${d.getMonth() + 1}/${d.getDate()}/${d.getFullYear()} ${hours12}:${minutes} ${meridiem}`; 2076 } 2077 2078 function headingFor(entry) { 2079 if (entry._isOriginal || entry._isoriginal) 2080 return 'Original Record'; 2081 2082 const validTo = entry.ValidTo != null ? entry.ValidTo : entry.validTo; 2083 const validFrom = entry.ValidFrom != null ? entry.ValidFrom : entry.validFrom; 2084 const formatted = formatHeadingDate(validTo) || formatHeadingDate(validFrom); 2085 return formatted ? `Change ${formatted}` : 'Change'; 2086 } 2087 2088 function localDayStart($input) { 2089 const selected = $input.datepicker('getDate'); 2090 if (!selected) 2091 return null; 2092 2093 return new Date(selected.getFullYear(), selected.getMonth(), selected.getDate()); 2094 } 2095 2096 function toUtcIso(date) { 2097 return date.toISOString(); 2098 } 2099 2100 function visibleKeys(entry) { 2101 return Object.keys(entry).filter(k => !hiddenKeys.test(k)); 2102 } 2103 2104 window.ShowHistoryModal = (tableClass, id) => { 2105 2106 $.fn.modalElement.open({ 2107 content: `<div class="change-log"> 2108 <h2>Change Log</h2> 2109 <div class="change-log-filters"> 2110 <label>Key 2111 <input type="text" data-change-log-key placeholder="Filter keys" autocomplete="off" /> 2112 </label> 2113 <label>From 2114 <input type="text" data-change-log-from class="DatePicker" placeholder="From date" autocomplete="off" /> 2115 </label> 2116 <label>To 2117 <input type="text" data-change-log-to class="DatePicker" placeholder="To date" autocomplete="off" /> 2118 </label> 2119 <button type="button" class="ForwardButton RoundButton" data-change-log-search title="Filter"> 2120 <i class="fa fa-sliders"></i> 2121 </button> 2122 </div> 2123 <div data-change-log><i class="fa fa-spinner fa-spin"></i></div> 2124 </div>` 2125 }); 2126 2127 const $log = $('[data-change-log]'); 2128 const $key = $('[data-change-log-key]'); 2129 const $from = $('[data-change-log-from]');
2130 const $to = $('[data-change-log-to]'); 2131 const $search = $('[data-change-log-search]'); 2132 let requestId = 0; 2133 2134 function loadChanges() { 2135 const currentRequest = ++requestId; 2136 $log.html('<i class="fa fa-spinner fa-spin"></i>'); 2137 2138 const params = new URLSearchParams({ tableClass }); 2139 if (id) 2140 params.set('id', id); 2141 2142 const key = ($key.val() || '').trim(); 2143 if (key) 2144 params.set('key', key); 2145 2146 const fromLocal = localDayStart($from); 2147 if (fromLocal) 2148 params.set('fromDate', toUtcIso(fromLocal)); 2149 2150 const toLocal = localDayStart($to); 2151 if (toLocal) { 2152 const toExclusive = new Date(toLocal.getFullYear(), toLocal.getMonth(), toLocal.getDate() + 1); 2153 params.set('toDate', toUtcIso(toExclusive)); 2154 } 2155 2156 fetch(`/api/reports/change-log?${params.toString()}`) 2157 .then(res => { 2158 if (currentRequest !== requestId) 2159 return null; 2160 2161 if (!res.ok) { 2162 $log.html('Failed to load'); 2163 return null; 2164 } 2165 2166 return res.json(); 2167 }) 2168 .then(list => { 2169 if (currentRequest !== requestId || list == null) 2170 return; 2171 2172 const lis = list.map(o => { 2173 const items = visibleKeys(o) 2174 .map(k => `<li>${formatLog(k, o[k])}</li>`) 2175 .join('\n'); 2176 return `<h3>${headingFor(o)}</h3><ul class='change-log-results'>${items}</ul>`; 2177 }); 2178 $log.html(lis.length > 0 2179 ? lis.join('\n') 2180 : 'No change history is within the search criteria'); 2181 }) 2182 .catch(() => { 2183 if (currentRequest === requestId) 2184 $log.html('Failed to load'); 2185 }); 2186 } 2187 2188 $from.add($to).datepicker({ 2189 dateFormat: 'm/d/yy', 2190 }); 2191 2192 $search.on('click', loadChanges); 2193 $key.on('keydown', e => { 2194 if (e.key === 'Enter') { 2195 e.preventDefault(); 2196 loadChanges(); 2197 } 2198 }); 2199 2200 loadChanges(); 2201 }; 2202 2203})(window, jQuery); 2204 2205 2206; 2207////pf: javascript/swipe.min.js 2208!function(t,e){t=t||{},"function"==typeof define&&define.amd?define([],function(){return t.Swipe=e(),t.Swipe}):"object"==typeof module&&module.exports?module.exports=e():t.Swipe=e()}(this,function(){var e,Q="object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global||this,W=Q.document;function Swipe(r,a){"use strict";function e(){}function n(t){return!!t&&("boolean"!=typeof t.cancelable||t.cancelable)}var o,t,s={},u={},l=(a=a||{}).auto||0,i=!1,c=function(t){setTimeout(t||e,0)};Element.prototype.matches||(Element.prototype.matches=Element.prototype.matchesSelector||Element.prototype.mozMatchesSelector||Element.prototype.msMatchesSelector||Element.prototype.oMatchesSelector||Element.prototype.webkitMatchesSelector||function(t){for(var e=(this.document||this.ownerDocument).querySelectorAll(t),n=e.length;0<=--n&&e.item(n)!==this;);return-1<n});var d={addEventListener:!!Q.addEventListener,passiveEvents:function(){var e=!1;try{var t=Object.defineProperty({},"passive",{get:function(){e=!0}});Q.addEventListener("testEvent",null,t),Q.removeEventListener("testEvent",null,t)}catch(t){e=!1}return e}(),touch:"ontouchstart"in Q||Q.DocumentTouch&&W instanceof DocumentTouch,transitions:function(t){var e,n=["transitionProperty","WebkitTransition","MozTransition","OTransition","msTransition"];for(e in n)if(void 0!==t.style[n[e]])return!0;return!1}(W.createElement("swipe"))};if(r){var v,f,m,h,p=r.children[0],E=parseInt(a.startSlide,10)||0,y=a.speed||300;a.continuous=void 0===a.continuous||a.continuous;var g,b,T=(g="direction",r.currentStyle?b=r.currentStyle[g]:Q.getComputedStyle&&(b=Q.getComputedStyle(r,null).getPropertyValue(g)),"rtl"===b?"right":"left");a.autoRestart=void 0!==a.autoRestart&&a.autoRestart;var x=function(n,i){i=i||100;var o=null;function s(){o&&clearTimeout(o)}function t(){var t=this,e=arguments;s(),o=setTimeout(function(){o=null,n.apply(t,e)},i)}return t.cancel=s,t}(S),L={handleEvent:function(t){if(!i||"resize"===t.type){switch(t.type){case"mousedown":case"touchstart":this.start(t);break;case"mousemove":case"touchmove":this.move(t);break;case"mouseup":case"mouseleave":case"touchend":this.end(t);break;case"webkitTransitionEnd":case"msTransitionEnd":case"oTransitionEnd":case"otransitionend":case"transitionend":this.transitionEnd(t);break;case"resize":x()}a.stopPropagation&&t.stopPropagation()}},start:function(t){var e=X(t)?t:t.touches[0];a.ignore&&e.target.matches(a.ignore)||(X(t)&&t.preventDefault(),s={x:e.pageX,y:e.pageY,time:+new Date},o=void 0,u={},X(t)?(p.addEventListener("mousemove",this,!1),p.addEventListener("mouseup",this,
2208!1),p.addEventListener("mouseleave",this,!1)):(p.addEventListener("touchmove",this,!!d.passiveEvents&&{passive:!1}),p.addEventListener("touchend",this,!1)),e=j(),t=v[E],a.dragStart&&a.dragStart(e,t))},move:function(t){var e;if(X(t))e=t;else{if(1<t.touches.length||t.scale&&1!==t.scale)return;a.disableScroll&&n(t)&&t.preventDefault(),e=t.touches[0]}u={x:e.pageX-s.x,y:e.pageY-s.y},void 0===o&&(o=!!(o||Math.abs(u.x)<Math.abs(u.y))),o||(n(t)&&t.preventDefault(),I(),a.continuous?(R(A(E-1),u.x+f[A(E-1)],0),R(E,u.x+f[E],0),R(A(E+1),u.x+f[A(E+1)],0)):(u.x=u.x/(!E&&0<u.x||E===v.length-1&&u.x<0?Math.abs(u.x)/m+1:1),R(E-1,u.x+f[E-1],0),R(E,u.x+f[E],0),R(E+1,u.x+f[E+1],0)))},end:function(t){var e=+new Date-s.time,n=Number(e)<250&&20<Math.abs(u.x)||Math.abs(u.x)>m/2,i=!E&&0<u.x||E===v.length-1&&u.x<0;a.continuous&&(i=!1);e=Math.abs(u.x)/u.x;o||(n&&!i?(E=e<0?(a.continuous?(P(A(E-1),-m,0),P(A(E+2),m,0)):P(E-1,-m,0),P(E,f[E]-m,y),P(A(E+1),f[A(E+1)]-m,y),A(E+1)):(a.continuous?(P(A(E+1),m,0),P(A(E-2),-m,0)):P(E+1,m,0),P(E,f[E]+m,y),P(A(E-1),f[A(E-1)]+m,y),A(E-1)),k(j(),v[E],e)):a.continuous?(P(A(E-1),-m,y),P(E,0,y),P(A(E+1),m,y)):(P(E-1,-m,y),P(E,0,y),P(E+1,m,y))),X(t)?(p.removeEventListener("mousemove",L,!1),p.removeEventListener("mouseup",L,!1),p.removeEventListener("mouseleave",L,!1)):(p.removeEventListener("touchmove",L,!!d.passiveEvents&&{passive:!1}),p.removeEventListener("touchend",L,!1)),e=j(),t=v[E],a.dragEnd&&a.dragEnd(e,t)},transitionEnd:function(t){parseInt(t.target.getAttribute("data-index"),10)===E&&((l||a.autoRestart)&&N(),z(j(),v[E]))}};return S(),C(),{setup:S,slide:function(t,e){I(),O(t,e)},prev:function(){I(),i||(a.continuous||E)&&O(E-1)},next:function(){I(),M()},restart:N,stop:I,getPos:j,disable:function(){I(),i=!0},enable:function(){i=!1,N()},getNumSlides:function(){return h},kill:function(){I(),r.style.visibility="",p.style.width="",p.style[T]="";var t=v.length;for(;t--;){d.transitions&&R(t,0,0);var e=v[t];e.getAttribute("data-cloned")&&e.parentElement.removeChild(e),e.style.width="",e.style[T]="",e.style.webkitTransitionDuration=e.style.MozTransitionDuration=e.style.msTransitionDuration=e.style.OTransitionDuration=e.style.transitionDuration="",e.style.webkitTransform=e.style.msTransform=e.style.MozTransform=e.style.OTransform=""}w(),x.cancel()}}}function w(){d.addEventListener?(p.removeEventListener("touchstart",L,!!d.passiveEvents&&{passive:!0}),p.removeEventListener("mousedown",L,!1),p.removeEventListener("webkitTransitionEnd",L,!1),p.removeEventListener("msTransitionEnd",L,!1),p.removeEventListener("oTransitionEnd",L,!1),p.removeEventListener("otransitionend",L,!1),p.removeEventListener("transitionend",L,!1),Q.removeEventListener("resize",L,!1)):Q.onresize=null}function D(t){t=t.cloneNode(!0);p.appendChild(t),t.setAttribute("data-cloned",!0),t.removeAttribute("id")}function S(t){if(null!=t)for(var e in t)a[e]=t[e];v=p.children,h=v.length;for(var n=0;n<v.length;n++)v[n].getAttribute("data-cloned")&&h--;if(v.length<2&&(a.continuous=!1),d.transitions&&a.continuous&&v.length<3&&(D(v[0]),D(v[1]),v=p.children),"right"===T)for(var i=0;i<v.length;i++)v[i].style.float="right";f=new Array(v.length),m=r.getBoundingClientRect().width||r.offsetWidth,p.style.width=v.length*m*2+"px";for(var o=v.length;o--;){var s=v[o];s.style.width=m+"px",s.setAttribute("data-index",o),d.transitions&&(s.style[T]=o*-m+"px",P(o,o<E?-m:E<o?m:0,0))}a.continuous&&d.transitions&&(P(A(E-1),-m,0),P(A(E+1),m,0)),d.transitions||(p.style[T]=E*-m+"px"),r.style.visibility="visible",w(),d.addEventListener?(d.touch&&p.addEventListener("touchstart",L,!!d.passiveEvents&&{passive:!0}),a.draggable&&p.addEventListener("mousedown",L,!1),d.transitions&&(p.addEventListener("webkitTransitionEnd",L,!1),p.addEventListener("msTransitionEnd",L,!1),p.addEventListener("oTransitionEnd",L,!1),p.addEventListener("otransitionend",L,!1),p.addEventListener("transitionend",L,!1)),Q.addEventListener("resize",L,!1)):Q.onresize=x}function M(){i||(a.continuous||E<v.length-1)&&O(E+1)}function k(t,e,n){a.callback&&a.callback(t,e,n)}function z(t,e){a.transitionEnd&&a.transitionEnd(t,e)}function A(t){return(v.length+t%v.length)%v.length}function j(){var t=E;return h<=t&&(t-=h),t}function O(t,e){if(t="number"!=typeof t?parseInt(t,10):t,E!==t){if(d.transitions){var n,i=Math.abs(E-t)/(E-t);a.continuous&&(n=i,(i=-f[A(t)]/m)!==n&&(t=-i*v.length+t));for(var o=Math.abs(E-t)-1;o--;)P(A((E<t?t:E)-o-1),m*i,0);t=A(t),P(E,m*i,e||y),P(t,0,e||y),a.continuous&&P(A(t-i),-m*i,0)}else t=A(t),function(e,n,i){if(!i)return p.style[T]=n+"px";var o=+new Date,s=setInterval(function(){var t=+new Date-o;if(i<t)return p.style[T]=n+"px",(l||a.autoRestart)&&N(),z(j(),v[E]),void clearInterval(s);p.style[T]=(n-e)*(Math.floor(t/i*100)/100)+e+"px"},4)}(E*-m,t*-m,e||y);E=t,c(function(){k(j(),v[E],i)})}}function P(t,e,n){R(t,e,n),f[t]=e}function R(t,e,n){t=v[t],t=t&&t.style;t&&(t.webkitTransitionDuration=t.MozTransitionDuration=t.msTransitionDuration=t.OTransitionDuration=t.transitionDuration=n+"ms",t.webkitTransform=t.msTransform=t.MozTransform=t.OTransform=t.transform="translateX("+e+"px)")}
2208function C(){(l=a.auto||0)&&(t=setTimeout(M,l))}function I(){l=0,clearTimeout(t)}function N(){I(),C()}function X(t){return/^mouse/.test(t.type)}}return(Q.jQuery||Q.Zepto)&&((e=Q.jQuery||Q.Zepto).fn.Swipe=function(t){return this.each(function(){e(this).data("Swipe",new Swipe(e(this)[0],t))})}),Swipe}); 2209 2210; 2211////pf: javascript/knockout/knockout-2.3.0.debug.js 2212// Knockout JavaScript library v2.3.0 2213// (c) Steven Sanderson - http://knockoutjs.com/ 2214// License: MIT (http://www.opensource.org/licenses/mit-license.php) 2215 2216(function(){ 2217var DEBUG=true; 2218(function(undefined){ 2219 // (0, eval)('this') is a robust way of getting a reference to the global object 2220 // For details, see http://stackoverflow.com/questions/14119988/return-this-0-evalthis/14120023#14120023 2221 var window = this || (0, eval)('this'), 2222 document = window['document'], 2223 navigator = window['navigator'], 2224 jQuery = window["jQuery"], 2225 JSON = window["JSON"]; 2226(function(factory) { 2227 // Support three module loading scenarios 2228 if (typeof require === 'function' && typeof exports === 'object' && typeof module === 'object') { 2229 // [1] CommonJS/Node.js 2230 var target = module['exports'] || exports; // module.exports is for Node.js 2231 factory(target); 2232 } else if (typeof define === 'function' && define['amd']) { 2233 // [2] AMD anonymous module 2234 define(['exports'], factory); 2235 } else { 2236 // [3] No module loader (plain <script> tag) - put directly in global namespace 2237 factory(window['ko'] = {}); 2238 } 2239}(function(koExports){ 2240// Internally, all KO objects are attached to koExports (even the non-exported ones whose names will be minified by the closure compiler). 2241// In the future, the following "ko" variable may be made distinct from "koExports" so that private objects are not externally reachable. 2242var ko = typeof koExports !== 'undefined' ? koExports : {}; 2243// Google Closure Compiler helpers (used only to make the minified file smaller) 2244ko.exportSymbol = function(koPath, object) { 2245 var tokens = koPath.split("."); 2246 2247 // In the future, "ko" may become distinct from "koExports" (so that non-exported objects are not reachable) 2248 // At that point, "target" would be set to: (typeof koExports !== "undefined" ? koExports : ko) 2249 var target = ko; 2250 2251 for (var i = 0; i < tokens.length - 1; i++) 2252 target = target[tokens[i]]; 2253 target[tokens[tokens.length - 1]] = object; 2254}; 2255ko.exportProperty = function(owner, publicName, object) { 2256 owner[publicName] = object; 2257}; 2258ko.version = "2.3.0"; 2259 2260ko.exportSymbol('version', ko.version); 2261ko.utils = (function () { 2262 var objectForEach = function(obj, action) { 2263 for (var prop in obj) { 2264 if (obj.hasOwnProperty(prop)) { 2265 action(prop, obj[prop]); 2266 } 2267 } 2268 }; 2269 2270 // Represent the known event types in a compact way, then at runtime transform it into a hash with event name as key (for fast lookup) 2271 var knownEvents = {}, knownEventTypesByEventName = {}; 2272 var keyEventTypeName = (navigator && /Firefox\/2/i.test(navigator.userAgent)) ? 'KeyboardEvent' : 'UIEvents'; 2273 knownEvents[keyEventTypeName] = ['keyup', 'keydown', 'keypress']; 2274 knownEvents['MouseEvents'] = ['click', 'dblclick', 'mousedown', 'mouseup', 'mousemove', 'mouseover', 'mouseout', 'mouseenter', 'mouseleave']; 2275 objectForEach(knownEvents, function(eventType, knownEventsForType) { 2276 if (knownEventsForType.length) { 2277 for (var i = 0, j = knownEventsForType.length; i < j; i++) 2278 knownEventTypesByEventName[knownEventsForType[i]] = eventType; 2279 } 2280 }); 2281 var eventsThatMustBeRegisteredUsingAttachEvent = { 'propertychange': true }; // Workaround for an IE9 issue - https://github.com/SteveSanderson/knockout/issues/406 2282 2283 // Detect IE versions for bug workarounds (uses IE conditionals, not UA string, for robustness) 2284 // Note that, since IE 10 does not support conditional comments, the following logic only detects IE < 10. 2285 // Currently this is by design, since IE 10+ behaves correctly when treated as a standard browser. 2286 // If there is a future need to detect specific versions of IE10+, we will amend this. 2287 var ieVersion = document && (function() { 2288 var version = 3, div = document.createElement('div'), iElems = div.getElementsByTagName('i'); 2289 2290 // Keep constructing conditional HTML blocks until we hit one that resolves to an empty fragment 2291 while ( 2292 div.innerHTML = '<!--[if gt IE ' + (++version) + ']><i></i><![endif]-->', 2293 iElems[0] 2294 ) {} 2295 return version > 4 ? version : undefined; 2296 }()); 2297 var isIe6 = ieVersion === 6, 2298 isIe7 = ieVersion === 7; 2299 2300 function isClickOnCheckableElement(element, eventType) { 2301 if ((ko.utils.tagNameLower(element) !== "input") || !element.type) return false; 2302 if (eventType.toLowerCase() != "click") return false; 2303 var inputType = element.type; 2304 return (inputType == "checkbox") || (inputType == "radio"); 2305 } 2306 2307 return { 2308 fieldsIncludedWithJsonPost: ['authenticity_token', /^__RequestVerificationToken(_.*)?$/], 2309 2310 arrayForEach: function (array, action) { 2311 for (var i = 0, j = array.length; i < j; i++) 2312 action(array[i]); 2313 }, 2314 2315 arrayIndexOf: function (array, item) { 2316 if (typeof Array.prototype.indexOf == "function") 2317 return Array.prototype.indexOf.call(array, item); 2318 for (var i = 0, j = array.length; i < j; i++) 2319 if (array[i] === item) 2320 return i; 2321 return -1; 2322 }, 2323 2324 arrayFirst: function (array, predicate, predicateOwner) { 2325 for (var i = 0, j = array.length; i < j; i++) 2326 if (predicate.call(predicateOwner, array[i])) 2327 return array[i]; 2328 return null; 2329 }, 2330 2331 arrayRemoveItem: function (array, itemToRemove) { 2332 var index = ko.utils.arrayIndexOf(array, itemToRemove); 2333 if (index >= 0) 2334 array.splice(index, 1); 2335 }, 2336 2337 arrayGetDistinctValues: function (array) { 2338 array = array || []; 2339 var result = []; 2340 for (var i = 0, j = array.length; i < j; i++) { 2341 if (ko.utils.arrayIndexOf(result, array[i]) < 0) 2342 result.push(array[i]); 2343 } 2344 return result; 2345 }, 2346 2347 arrayMap: function (array, mapping) { 2348 array = array || []; 2349 var result = []; 2350 for (var i = 0, j = array.length; i < j; i++) 2351 result.push(mapping(array[i])); 2352 return result; 2353 }, 2354 2355 arrayFilter: function (array, predicate) { 2356 array = array || []; 2357 var result = []; 2358 for (var i = 0, j = array.length; i < j; i++) 2359 if (predicate(array[i])) 2360 result.push(array[i]); 2361 return result; 2362 }, 2363 2364 arrayPushAll: function (array, valuesToPush) { 2365 if (valuesToPush instanceof Array) 2366 array.push.apply(array, valuesToPush); 2367 else 2368 for (var i = 0, j = valuesToPush.length; i < j; i++) 2369 array.push(valuesToPush[i]); 2370 return array; 2371 }, 2372 2373 addOrRemoveItem: function(array, value, included) { 2374 var existingEntryIndex = array.indexOf ? array.indexOf(value) : ko.utils.arrayIndexOf(array, value); 2375 if (existingEntryIndex < 0) { 2376 if (included) 2377 array.push(value); 2378 } else { 2379 if (!included) 2380 array.splice(existingEntryIndex, 1); 2381 } 2382 }, 2383 2384 extend: function (target, source) { 2385 if (source) { 2386 for(var prop in source) { 2387 if(source.hasOwnProperty(prop)) { 2388 target[prop] = source[prop]; 2389 } 2390 } 2391 } 2392 return target; 2393 }, 2394 2395 objectForEach: objectForEach, 2396 2397 emptyDomNode: function (domNode) { 2398 while (domNode.firstChild) { 2399 ko.removeNode(domNode.firstChild); 2400 } 2401 }, 2402 2403 moveCleanedNodesToContainerElement: function(nodes) { 2404 // Ensure it's a real array, as we're about to reparent the nodes and 2405 // we don't want the underlying collection to change while we're doing that. 2406 var nodesArray = ko.utils.makeArray(nodes); 2407 2408 var container = document.createElement('div'); 2409 for (var i = 0, j = nodesArray.length; i < j; i++) { 2410 container.appendChild(ko.cleanNode(nodesArray[i])); 2411 } 2412 return container; 2413 }, 2414 2415 cloneNodes: function (nodesArray, shouldCleanNodes) { 2416 for (var i = 0, j = nodesArray.length, newNodesArray = []; i < j; i++) { 2417 var clonedNode = nodesArray[i].cloneNode(true); 2418 newNodesArray.push(shouldCleanNodes ? ko.cleanNode(clonedNode) : clonedNode); 2419 } 2420 return newNodesArray; 2421 }, 2422 2423 setDomNodeChildren: function (domNode, childNodes) { 2424 ko.utils.emptyDomNode(domNode); 2425 if (childNodes) { 2426 for (var i = 0, j = childNodes.length; i < j; i++) 2427 domNode.appendChild(childNodes[i]); 2428 } 2429 }, 2430 2431 replaceDomNodes: function (nodeToReplaceOrNodeArray, newNodesArray) { 2432 var nodesToReplaceArray = nodeToReplaceOrNodeArray.nodeType ? [nodeToReplaceOrNodeArray] : nodeToReplaceOrNodeArray; 2433 if (nodesToReplaceArray.length > 0) { 2434 var insertionPoint = nodesToReplaceArray[0]; 2435 var parent = insertionPoint.parentNode; 2436 for (var i = 0, j = newNodesArray.length; i < j; i++) 2437 parent.insertBefore(newNodesArray[i], insertionPoint); 2438 for (var i = 0, j = nodesToReplaceArray.length; i < j; i++) { 2439 ko.removeNode(nodesToReplaceArray[i]); 2440 } 2441 } 2442 }, 2443 2444 setOptionNodeSelectionState: function (optionNode, isSelected) { 2445 // IE6 sometimes throws "unknown error" if you try to write to .selected directly, whereas Firefox struggles with setAttribute. Pick one based on browser. 2446 if (ieVersion < 7) 2447 optionNode.setAttribute("selected", isSelected); 2448 else 2449 optionNode.selected = isSelected; 2450 }, 2451
2452 stringTrim: function (string) { 2453 return string === null || string === undefined ? '' : 2454 string.trim ? 2455 string.trim() : 2456 string.toString().replace(/^[\s\xa0]+|[\s\xa0]+$/g, ''); 2457 }, 2458 2459 stringTokenize: function (string, delimiter) { 2460 var result = []; 2461 var tokens = (string || "").split(delimiter); 2462 for (var i = 0, j = tokens.length; i < j; i++) { 2463 var trimmed = ko.utils.stringTrim(tokens[i]); 2464 if (trimmed !== "") 2465 result.push(trimmed); 2466 } 2467 return result; 2468 }, 2469 2470 stringStartsWith: function (string, startsWith) { 2471 string = string || ""; 2472 if (startsWith.length > string.length) 2473 return false; 2474 return string.substring(0, startsWith.length) === startsWith; 2475 }, 2476 2477 domNodeIsContainedBy: function (node, containedByNode) { 2478 if (containedByNode.compareDocumentPosition) 2479 return (containedByNode.compareDocumentPosition(node) & 16) == 16; 2480 while (node != null) { 2481 if (node == containedByNode) 2482 return true; 2483 node = node.parentNode; 2484 } 2485 return false; 2486 }, 2487 2488 domNodeIsAttachedToDocument: function (node) { 2489 return ko.utils.domNodeIsContainedBy(node, node.ownerDocument); 2490 }, 2491 2492 anyDomNodeIsAttachedToDocument: function(nodes) { 2493 return !!ko.utils.arrayFirst(nodes, ko.utils.domNodeIsAttachedToDocument); 2494 }, 2495 2496 tagNameLower: function(element) { 2497 // For HTML elements, tagName will always be upper case; for XHTML elements, it'll be lower case. 2498 // Possible future optimization: If we know it's an element from an XHTML document (not HTML), 2499 // we don't need to do the .toLowerCase() as it will always be lower case anyway. 2500 return element && element.tagName && element.tagName.toLowerCase(); 2501 }, 2502 2503 registerEventHandler: function (element, eventType, handler) { 2504 var mustUseAttachEvent = ieVersion && eventsThatMustBeRegisteredUsingAttachEvent[eventType]; 2505 if (!mustUseAttachEvent && typeof jQuery != "undefined") { 2506 if (isClickOnCheckableElement(element, eventType)) { 2507 // For click events on checkboxes, jQuery interferes with the event handling in an awkward way: 2508 // it toggles the element checked state *after* the click event handlers run, whereas native 2509 // click events toggle the checked state *before* the event handler. 2510 // Fix this by intecepting the handler and applying the correct checkedness before it runs. 2511 var originalHandler = handler; 2512 handler = function(event, eventData) { 2513 var jQuerySuppliedCheckedState = this.checked; 2514 if (eventData) 2515 this.checked = eventData.checkedStateBeforeEvent !== true; 2516 originalHandler.call(this, event); 2517 this.checked = jQuerySuppliedCheckedState; // Restore the state jQuery applied 2518 }; 2519 } 2520 jQuery(element)['bind'](eventType, handler); 2521 } else if (!mustUseAttachEvent && typeof element.addEventListener == "function") 2522 element.addEventListener(eventType, handler, false); 2523 else if (typeof element.attachEvent != "undefined") { 2524 var attachEventHandler = function (event) { handler.call(element, event); }, 2525 attachEventName = "on" + eventType; 2526 element.attachEvent(attachEventName, attachEventHandler); 2527 2528 // IE does not dispose attachEvent handlers automatically (unlike with addEventListener) 2529 // so to avoid leaks, we have to remove them manually. See bug #856 2530 ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 2531 element.detachEvent(attachEventName, attachEventHandler); 2532 }); 2533 } else 2534 throw new Error("Browser doesn't support addEventListener or attachEvent"); 2535 }, 2536 2537 triggerEvent: function (element, eventType) { 2538 if (!(element && element.nodeType)) 2539 throw new Error("element must be a DOM node when calling triggerEvent"); 2540 2541 if (typeof jQuery != "undefined") { 2542 var eventData = []; 2543 if (isClickOnCheckableElement(element, eventType)) { 2544 // Work around the jQuery "click events on checkboxes" issue described above by storing the original checked state before triggering the handler 2545 eventData.push({ checkedStateBeforeEvent: element.checked }); 2546 } 2547 jQuery(element)['trigger'](eventType, eventData); 2548 } else if (typeof document.createEvent == "function") { 2549 if (typeof element.dispatchEvent == "function") { 2550 var eventCategory = knownEventTypesByEventName[eventType] || "HTMLEvents"; 2551 var event = document.createEvent(eventCategory); 2552 event.initEvent(eventType, true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, element); 2553 element.dispatchEvent(event); 2554 } 2555 else 2556 throw new Error("The supplied element doesn't support dispatchEvent"); 2557 } else if (typeof element.fireEvent != "undefined") { 2558 // Unlike other browsers, IE doesn't change the checked state of checkboxes/radiobuttons when you trigger their "click" event 2559 // so to make it consistent, we'll do it manually here 2560 if (isClickOnCheckableElement(element, eventType)) 2561 element.checked = element.checked !== true; 2562 element.fireEvent("on" + eventType); 2563 } 2564 else 2565 throw new Error("Browser doesn't support triggering events"); 2566 }, 2567 2568 unwrapObservable: function (value) {
2569 return ko.isObservable(value) ? value() : value; 2570 }, 2571 2572 peekObservable: function (value) { 2573 return ko.isObservable(value) ? value.peek() : value; 2574 }, 2575 2576 toggleDomNodeCssClass: function (node, classNames, shouldHaveClass) { 2577 if (classNames) { 2578 var cssClassNameRegex = /\S+/g, 2579 currentClassNames = node.className.match(cssClassNameRegex) || []; 2580 ko.utils.arrayForEach(classNames.match(cssClassNameRegex), function(className) { 2581 ko.utils.addOrRemoveItem(currentClassNames, className, shouldHaveClass); 2582 }); 2583 node.className = currentClassNames.join(" "); 2584 } 2585 }, 2586 2587 setTextContent: function(element, textContent) { 2588 var value = ko.utils.unwrapObservable(textContent); 2589 if ((value === null) || (value === undefined)) 2590 value = ""; 2591 2592 // We need there to be exactly one child: a text node. 2593 // If there are no children, more than one, or if it's not a text node, 2594 // we'll clear everything and create a single text node. 2595 var innerTextNode = ko.virtualElements.firstChild(element); 2596 if (!innerTextNode || innerTextNode.nodeType != 3 || ko.virtualElements.nextSibling(innerTextNode)) { 2597 ko.virtualElements.setDomNodeChildren(element, [document.createTextNode(value)]); 2598 } else { 2599 innerTextNode.data = value; 2600 } 2601 2602 ko.utils.forceRefresh(element); 2603 }, 2604 2605 setElementName: function(element, name) { 2606 element.name = name; 2607 2608 // Workaround IE 6/7 issue 2609 // - https://github.com/SteveSanderson/knockout/issues/197 2610 // - http://www.matts411.com/post/setting_the_name_attribute_in_ie_dom/ 2611 if (ieVersion <= 7) { 2612 try { 2613 element.mergeAttributes(document.createElement("<input name='" + element.name + "'/>"), false); 2614 } 2615 catch(e) {} // For IE9 with doc mode "IE9 Standards" and browser mode "IE9 Compatibility View" 2616 } 2617 }, 2618 2619 forceRefresh: function(node) { 2620 // Workaround for an IE9 rendering bug - https://github.com/SteveSanderson/knockout/issues/209 2621 if (ieVersion >= 9) { 2622 // For text nodes and comment nodes (most likely virtual elements), we will have to refresh the container 2623 var elem = node.nodeType == 1 ? node : node.parentNode; 2624 if (elem.style) 2625 elem.style.zoom = elem.style.zoom; 2626 } 2627 }, 2628 2629 ensureSelectElementIsRenderedCorrectly: function(selectElement) { 2630 // Workaround for IE9 rendering bug - it doesn't reliably display all the text in dynamically-added select boxes unless you force it to re-render by updating the width. 2631 // (See https://github.com/SteveSanderson/knockout/issues/312, http://stackoverflow.com/questions/5908494/select-only-shows-first-char-of-selected-option) 2632 // Also fixes IE7 and IE8 bug that causes selects to be zero width if enclosed by 'if' or 'with'. (See issue #839) 2633 if (ieVersion) { 2634 var originalWidth = selectElement.style.width; 2635 selectElement.style.width = 0; 2636 selectElement.style.width = originalWidth; 2637 } 2638 }, 2639 2640 range: function (min, max) { 2641 min = ko.utils.unwrapObservable(min); 2642 max = ko.utils.unwrapObservable(max); 2643 var result = []; 2644 for (var i = min; i <= max; i++) 2645 result.push(i); 2646 return result; 2647 }, 2648 2649 makeArray: function(arrayLikeObject) { 2650 var result = []; 2651 for (var i = 0, j = arrayLikeObject.length; i < j; i++) { 2652 result.push(arrayLikeObject[i]); 2653 }; 2654 return result; 2655 }, 2656 2657 isIe6 : isIe6, 2658 isIe7 : isIe7, 2659 ieVersion : ieVersion, 2660 2661 getFormFields: function(form, fieldName) { 2662 var fields = ko.utils.makeArray(form.getElementsByTagName("input")).concat(ko.utils.makeArray(form.getElementsByTagName("textarea"))); 2663 var isMatchingField = (typeof fieldName == 'string') 2664 ? function(field) { return field.name === fieldName } 2665 : function(field) { return fieldName.test(field.name) };
2665 // Treat fieldName as regex or object containing predicate 2666 var matches = []; 2667 for (var i = fields.length - 1; i >= 0; i--) { 2668 if (isMatchingField(fields[i])) 2669 matches.push(fields[i]); 2670 }; 2671 return matches; 2672 }, 2673 2674 parseJson: function (jsonString) { 2675 if (typeof jsonString == "string") { 2676 jsonString = ko.utils.stringTrim(jsonString); 2677 if (jsonString) { 2678 if (JSON && JSON.parse) // Use native parsing where available 2679 return JSON.parse(jsonString); 2680 return (new Function("return " + jsonString))(); // Fallback on less safe parsing for older browsers 2681 } 2682 } 2683 return null; 2684 }, 2685 2686 stringifyJson: function (data, replacer, space) { // replacer and space are optional 2687 if (!JSON || !JSON.stringify) 2688 throw new Error("Cannot find JSON.stringify(). Some browsers (e.g., IE < 8) don't support it natively, but you can overcome this by adding a script reference to json2.js, downloadable from http://www.json.org/json2.js"); 2689 return JSON.stringify(ko.utils.unwrapObservable(data), replacer, space); 2690 }, 2691 2692 postJson: function (urlOrForm, data, options) { 2693 options = options || {}; 2694 var params = options['params'] || {}; 2695 var includeFields = options['includeFields'] || this.fieldsIncludedWithJsonPost; 2696 var url = urlOrForm; 2697 2698 // If we were given a form, use its 'action' URL and pick out any requested field values 2699 if((typeof urlOrForm == 'object') && (ko.utils.tagNameLower(urlOrForm) === "form")) { 2700 var originalForm = urlOrForm; 2701 url = originalForm.action; 2702 for (var i = includeFields.length - 1; i >= 0; i--) { 2703 var fields = ko.utils.getFormFields(originalForm, includeFields[i]); 2704 for (var j = fields.length - 1; j >= 0; j--) 2705 params[fields[j].name] = fields[j].value; 2706 } 2707 } 2708 2709 data = ko.utils.unwrapObservable(data); 2710 var form = document.createElement("form"); 2711 form.style.display = "none"; 2712 form.action = url; 2713 form.method = "post"; 2714 for (var key in data) { 2715 // Since 'data' this is a model object, we include all properties including those inherited from its prototype 2716 var input = document.createElement("input"); 2717 input.name = key; 2718 input.value = ko.utils.stringifyJson(ko.utils.unwrapObservable(data[key])); 2719 form.appendChild(input); 2720 } 2721 objectForEach(params, function(key, value) { 2722 var input = document.createElement("input"); 2723 input.name = key; 2724 input.value = value; 2725 form.appendChild(input); 2726 }); 2727 document.body.appendChild(form); 2728 options['submitter'] ? options['submitter'](form) : form.submit(); 2729 setTimeout(function () { form.parentNode.removeChild(form); }, 0); 2730 } 2731 } 2732}()); 2733 2734ko.exportSymbol('utils', ko.utils); 2735ko.exportSymbol('utils.arrayForEach', ko.utils.arrayForEach); 2736ko.exportSymbol('utils.arrayFirst', ko.utils.arrayFirst); 2737ko.exportSymbol('utils.arrayFilter', ko.utils.arrayFilter); 2738ko.exportSymbol('utils.arrayGetDistinctValues', ko.utils.arrayGetDistinctValues); 2739ko.exportSymbol('utils.arrayIndexOf', ko.utils.arrayIndexOf); 2740ko.exportSymbol('utils.arrayMap', ko.utils.arrayMap); 2741ko.exportSymbol('utils.arrayPushAll', ko.utils.arrayPushAll); 2742ko.exportSymbol('utils.arrayRemoveItem', ko.utils.arrayRemoveItem); 2743ko.exportSymbol('utils.extend', ko.utils.extend); 2744ko.exportSymbol('utils.fieldsIncludedWithJsonPost', ko.utils.fieldsIncludedWithJsonPost); 2745ko.exportSymbol('utils.getFormFields', ko.utils.getFormFields); 2746ko.exportSymbol('utils.peekObservable', ko.utils.peekObservable); 2747ko.exportSymbol('utils.postJson', ko.utils.postJson); 2748ko.exportSymbol('utils.parseJson', ko.utils.parseJson); 2749ko.exportSymbol('utils.registerEventHandler', ko.utils.registerEventHandler); 2750ko.exportSymbol('utils.stringifyJson', ko.utils.stringifyJson); 2751ko.exportSymbol('utils.range', ko.utils.range); 2752ko.exportSymbol('utils.toggleDomNodeCssClass', ko.utils.toggleDomNodeCssClass); 2753ko.exportSymbol('utils.triggerEvent', ko.utils.triggerEvent); 2754ko.exportSymbol('utils.unwrapObservable', ko.utils.unwrapObservable); 2755ko.exportSymbol('utils.objectForEach', ko.utils.objectForEach); 2756ko.exportSymbol('utils.addOrRemoveItem', ko.utils.addOrRemoveItem); 2757ko.exportSymbol('unwrap', ko.utils.unwrapObservable); // Convenient shorthand, because this is used so commonly 2758 2759if (!Function.prototype['bind']) { 2760 // Function.prototype.bind is a standard part of ECMAScript 5th Edition (December 2009, http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf) 2761 // In case the browser doesn't implement it natively, provide a JavaScript implementation. This implementation is based on the one in prototype.js 2762 Function.prototype['bind'] = function (object) { 2763 var originalFunction = this, args = Array.prototype.slice.call(arguments), object = args.shift(); 2764 return function () { 2765 return originalFunction.apply(object, args.concat(Array.prototype.slice.call(arguments))); 2766 }; 2767 }; 2768} 2769 2770ko.utils.domData = new (function () { 2771 var uniqueId = 0; 2772 var dataStoreKeyExpandoPropertyName = "__ko__" + (new Date).getTime(); 2773 var dataStore = {}; 2774 return { 2775 get: function (node, key) { 2776 var allDataForNode = ko.utils.domData.getAll(node, false); 2777 return allDataForNode === undefined ? undefined : allDataForNode[key]; 2778 }, 2779 set: function (node, key, value) { 2780 if (value === undefined) { 2781 // Make sure we don't actually create a new domData key if we are actually deleting a value 2782 if (ko.utils.domData.getAll(node, false) === undefined) 2783 return; 2784 } 2785 var allDataForNode = ko.utils.domData.getAll(node, true); 2786 allDataForNode[key] = value; 2787 }, 2788 getAll: function (node, createIfNotFound) { 2789 var dataStoreKey = node[dataStoreKeyExpandoPropertyName]; 2790 var hasExistingDataStore = dataStoreKey && (dataStoreKey !== "null") && dataStore[dataStoreKey]; 2791 if (!hasExistingDataStore) { 2792 if (!createIfNotFound) 2793 return undefined; 2794 dataStoreKey = node[dataStoreKeyExpandoPropertyName] = "ko" + uniqueId++; 2795 dataStore[dataStoreKey] = {}; 2796 } 2797 return dataStore[dataStoreKey]; 2798 }, 2799 clear: function (node) { 2800 var dataStoreKey = node[dataStoreKeyExpandoPropertyName]; 2801 if (dataStoreKey) { 2802 delete dataStore[dataStoreKey]; 2803 node[dataStoreKeyExpandoPropertyName] = null; 2804 return true; // Exposing "did clean" flag purely so specs can infer whether things have been cleaned up as intended 2805 } 2806 return false; 2807 } 2808 } 2809})(); 2810 2811ko.exportSymbol('utils.domData', ko.utils.domData); 2812ko.exportSymbol('utils.domData.clear', ko.utils.domData.clear); // Exporting only so specs can clear up after themselves fully 2813 2814ko.utils.domNodeDisposal = new (function () { 2815 var domDataKey = "__ko_domNodeDisposal__" + (new Date).getTime(); 2816 var cleanableNodeTypes = { 1: true, 8: true, 9: true }; // Element, Comment, Document 2817 var cleanableNodeTypesWithDescendants = { 1: true, 9: true }; // Element, Document 2818 2819 function getDisposeCallbacksCollection(node, createIfNotFound) { 2820 var allDisposeCallbacks = ko.utils.domData.get(node, domDataKey); 2821 if ((allDisposeCallbacks === undefined) && createIfNotFound) { 2822 allDisposeCallbacks = []; 2823 ko.utils.domData.set(node, domDataKey, allDisposeCallbacks); 2824 } 2825 return allDisposeCallbacks; 2826 } 2827 function destroyCallbacksCollection(node) { 2828 ko.utils.domData.set(node, domDataKey, undefined); 2829 } 2830 2831 function cleanSingleNode(node) { 2832 // Run all the dispose callbacks 2833 var callbacks = getDisposeCallbacksCollection(node, false); 2834 if (callbacks) { 2835 callbacks = callbacks.slice(0); // Clone, as the array may be modified during iteration (typically, callbacks will remove themselves) 2836 for (var i = 0; i < callbacks.length; i++) 2837 callbacks[i](node); 2838 } 2839 2840 // Also erase the DOM data 2841 ko.utils.domData.clear(node); 2842 2843 // Special support for jQuery here because it's so commonly used. 2844 // Many jQuery plugins (including jquery.tmpl) store data using jQuery's equivalent of domData 2845 // so notify it to tear down any resources associated with the node & descendants here. 2846 if ((typeof jQuery == "function") && (typeof jQuery['cleanData'] == "function")) 2847 jQuery['cleanData']([node]); 2848 2849 // Also clear any immediate-child comment nodes, as these wouldn't have been found by 2850 // node.getElementsByTagName("*") in cleanNode() (comment nodes aren't elements) 2851 if (cleanableNodeTypesWithDescendants[node.nodeType]) 2852 cleanImmediateCommentTypeChildren(node); 2853 } 2854 2855 function cleanImmediateCommentTypeChildren(nodeWithChildren) { 2856 var child, nextChild = nodeWithChildren.firstChild; 2857 while (child = nextChild) { 2858 nextChild = child.nextSibling; 2859 if (child.nodeType === 8) 2860 cleanSingleNode(child); 2861 } 2862 } 2863 2864 return { 2865 addDisposeCallback : function(node, callback) { 2866 if (typeof callback != "function") 2867 throw new Error("Callback must be a function"); 2868 getDisposeCallbacksCollection(node, true).push(callback); 2869 }, 2870 2871 removeDisposeCallback : function(node, callback) { 2872 var callbacksCollection = getDisposeCallbacksCollection(node, false); 2873 if (callbacksCollection) { 2874 ko.utils.arrayRemoveItem(callbacksCollection, callback); 2875 if (callbacksCollection.length == 0) 2876 destroyCallbacksCollection(node); 2877 } 2878 }, 2879 2880 cleanNode : function(node) { 2881 // First clean this node, where applicable 2882 if (cleanableNodeTypes[node.nodeType]) { 2883 cleanSingleNode(node); 2884
2885 // ... then its descendants, where applicable 2886 if (cleanableNodeTypesWithDescendants[node.nodeType]) { 2887 // Clone the descendants list in case it changes during iteration 2888 var descendants = []; 2889 ko.utils.arrayPushAll(descendants, node.getElementsByTagName("*")); 2890 for (var i = 0, j = descendants.length; i < j; i++) 2891 cleanSingleNode(descendants[i]); 2892 } 2893 } 2894 return node; 2895 }, 2896 2897 removeNode : function(node) { 2898 ko.cleanNode(node); 2899 if (node.parentNode) 2900 node.parentNode.removeChild(node); 2901 } 2902 } 2903})(); 2904ko.cleanNode = ko.utils.domNodeDisposal.cleanNode; // Shorthand name for convenience 2905ko.removeNode = ko.utils.domNodeDisposal.removeNode; // Shorthand name for convenience 2906ko.exportSymbol('cleanNode', ko.cleanNode); 2907ko.exportSymbol('removeNode', ko.removeNode); 2908ko.exportSymbol('utils.domNodeDisposal', ko.utils.domNodeDisposal); 2909ko.exportSymbol('utils.domNodeDisposal.addDisposeCallback', ko.utils.domNodeDisposal.addDisposeCallback); 2910ko.exportSymbol('utils.domNodeDisposal.removeDisposeCallback', ko.utils.domNodeDisposal.removeDisposeCallback); 2911(function () { 2912 var leadingCommentRegex = /^(\s*)<!--(.*?)-->/; 2913 2914 function simpleHtmlParse(html) { 2915 // Based on jQuery's "clean" function, but only accounting for table-related elements. 2916 // If you have referenced jQuery, this won't be used anyway - KO will use jQuery's "clean" function directly 2917 2918 // Note that there's still an issue in IE < 9 whereby it will discard comment nodes that are the first child of 2919 // a descendant node. For example: "<div><!-- mycomment -->abc</div>" will get parsed as "<div>abc</div>" 2920 // This won't affect anyone who has referenced jQuery, and there's always the workaround of inserting a dummy node 2921 // (possibly a text node) in front of the comment. So, KO does not attempt to workaround this IE issue automatically at present. 2922 2923 // Trim whitespace, otherwise indexOf won't work as expected 2924 var tags = ko.utils.stringTrim(html).toLowerCase(), div = document.createElement("div"); 2925 2926 // Finds the first match from the left column, and returns the corresponding "wrap" data from the right column 2927 var wrap = tags.match(/^<(thead|tbody|tfoot)/) && [1, "<table>", "</table>"] || 2928 !tags.indexOf("<tr") && [2, "<table><tbody>", "</tbody></table>"] || 2929 (!tags.indexOf("<td") || !tags.indexOf("<th")) && [3, "<table><tbody><tr>", "</tr></tbody></table>"] || 2930 /* anything else */ [0, "", ""]; 2931 2932 // Go to html and back, then peel off extra wrappers 2933 // Note that we always prefix with some dummy text, because otherwise, IE<9 will strip out leading comment nodes in descendants. Total madness. 2934 var markup = "ignored<div>" + wrap[1] + html + wrap[2] + "</div>"; 2935 if (typeof window['innerShiv'] == "function") { 2936 div.appendChild(window['innerShiv'](markup)); 2937 } else { 2938 div.innerHTML = markup; 2939 } 2940 2941 // Move to the right depth 2942 while (wrap[0]--) 2943 div = div.lastChild; 2944 2945 return ko.utils.makeArray(div.lastChild.childNodes); 2946 } 2947 2948 function jQueryHtmlParse(html) { 2949 // jQuery's "parseHTML" function was introduced in jQuery 1.8.0 and is a documented public API. 2950 if (jQuery['parseHTML']) { 2951 return jQuery['parseHTML'](html) || []; // Ensure we always return an array and never null 2952 } else { 2953 // For jQuery < 1.8.0, we fall back on the undocumented internal "clean" function. 2954 var elems = jQuery['clean']([html]); 2955 2956 // As of jQuery 1.7.1, jQuery parses the HTML by appending it to some dummy parent nodes held in an in-memory document fragment. 2957 // Unfortunately, it never clears the dummy parent nodes from the document fragment, so it leaks memory over time. 2958 // Fix this by finding the top-most dummy parent element, and detaching it from its owner fragment. 2959 if (elems && elems[0]) { 2960 // Find the top-most parent element that's a direct child of a document fragment 2961 var elem = elems[0]; 2962 while (elem.parentNode && elem.parentNode.nodeType !== 11 /* i.e., DocumentFragment */) 2963 elem = elem.parentNode; 2964 // ... then detach it 2965 if (elem.parentNode) 2966 elem.parentNode.removeChild(elem); 2967 } 2968 2969 return elems; 2970 } 2971 } 2972 2973 ko.utils.parseHtmlFragment = function(html) { 2974 return typeof jQuery != 'undefined' ? jQueryHtmlParse(html) // As below, benef
vendor: 5,642 bytes, lines 2974-3099
2974it from jQuery's optimisations where possible 2975 : simpleHtmlParse(html); // ... otherwise, this simple logic will do in most common cases. 2976 }; 2977 2978 ko.utils.setHtml = function(node, html) { 2979 ko.utils.emptyDomNode(node); 2980 2981 // There's no legitimate reason to display a stringified observable without unwrapping it, so we'll unwrap it 2982 html = ko.utils.unwrapObservable(html); 2983 2984 if ((html !== null) && (html !== undefined)) { 2985 if (typeof html != 'string') 2986 html = html.toString(); 2987 2988 // jQuery contains a lot of sophisticated code to parse arbitrary HTML fragments, 2989 // for example <tr> elements which are not normally allowed to exist on their own. 2990 // If you've referenced jQuery we'll use that rather than duplicating its code. 2991 if (typeof jQuery != 'undefined') { 2992 jQuery(node)['html'](html); 2993 } else { 2994 // ... otherwise, use KO's own parsing logic. 2995 var parsedNodes = ko.utils.parseHtmlFragment(html); 2996 for (var i = 0; i < parsedNodes.length; i++) 2997 node.appendChild(parsedNodes[i]); 2998 } 2999 } 3000 }; 3001})(); 3002 3003ko.exportSymbol('utils.parseHtmlFragment', ko.utils.parseHtmlFragment); 3004ko.exportSymbol('utils.setHtml', ko.utils.setHtml); 3005 3006ko.memoization = (function () { 3007 var memos = {}; 3008 3009 function randomMax8HexChars() { 3010 return (((1 + Math.random()) * 0x100000000) | 0).toString(16).substring(1); 3011 } 3012 function generateRandomId() { 3013 return randomMax8HexChars() + randomMax8HexChars(); 3014 } 3015 function findMemoNodes(rootNode, appendToArray) { 3016 if (!rootNode) 3017 return; 3018 if (rootNode.nodeType == 8) { 3019 var memoId = ko.memoization.parseMemoText(rootNode.nodeValue); 3020 if (memoId != null) 3021 appendToArray.push({ domNode: rootNode, memoId: memoId }); 3022 } else if (rootNode.nodeType == 1) { 3023 for (var i = 0, childNodes = rootNode.childNodes, j = childNodes.length; i < j; i++) 3024 findMemoNodes(childNodes[i], appendToArray); 3025 } 3026 } 3027 3028 return { 3029 memoize: function (callback) { 3030 if (typeof callback != "function") 3031 throw new Error("You can only pass a function to ko.memoization.memoize()"); 3032 var memoId = generateRandomId(); 3033 memos[memoId] = callback; 3034 return "<!--[ko_memo:" + memoId + "]-->"; 3035 }, 3036 3037 unmemoize: function (memoId, callbackParams) { 3038 var callback = memos[memoId]; 3039 if (callback === undefined) 3040 throw new Error("Couldn't find any memo with ID " + memoId + ". Perhaps it's already been unmemoized."); 3041 try { 3042 callback.apply(null, callbackParams || []); 3043 return true; 3044 } 3045 finally { delete memos[memoId]; } 3046 }, 3047 3048 unmemoizeDomNodeAndDescendants: function (domNode, extraCallbackParamsArray) { 3049 var memos = []; 3050 findMemoNodes(domNode, memos); 3051 for (var i = 0, j = memos.length; i < j; i++) { 3052 var node = memos[i].domNode; 3053 var combinedParams = [node]; 3054 if (extraCallbackParamsArray) 3055 ko.utils.arrayPushAll(combinedParams, extraCallbackParamsArray); 3056 ko.memoization.unmemoize(memos[i].memoId, combinedParams); 3057 node.nodeValue = ""; // Neuter this node so we don't try to unmemoize it again 3058 if (node.parentNode) 3059 node.parentNode.removeChild(node); // If possible, erase it totally (not always possible - someone else might just hold a reference to it then call unmemoizeDomNodeAndDescendants again) 3060 } 3061 }, 3062 3063 parseMemoText: function (memoText) { 3064 var match = memoText.match(/^\[ko_memo\:(.*?)\]$/); 3065 return match ? match[1] : null; 3066 } 3067 }; 3068})(); 3069 3070ko.exportSymbol('memoization', ko.memoization); 3071ko.exportSymbol('memoization.memoize', ko.memoization.memoize); 3072ko.exportSymbol('memoization.unmemoize', ko.memoization.unmemoize); 3073ko.exportSymbol('memoization.parseMemoText', ko.memoization.parseMemoText); 3074ko.exportSymbol('memoization.unmemoizeDomNodeAndDescendants', ko.memoization.unmemoizeDomNodeAndDescendants); 3075ko.extenders = { 3076 'throttle': function(target, timeout) { 3077 // Throttling means two things: 3078 3079 // (1) For dependent observables, we throttle *evaluations* so that, no matter how fast its dependencies 3080 // notify updates, the target doesn't re-evaluate (and hence doesn't notify) faster than a certain rate 3081 target['throttleEvaluation'] = timeout; 3082 3083 // (2) For writable targets (observables, or writable dependent observables), we throttle *writes* 3084 // so the target cannot change value synchronously or faster than a certain rate 3085 var writeTimeoutInstance = null; 3086 return ko.dependentObservable({ 3087 'read': target, 3088 'write': function(value) { 3089 clearTimeout(writeTimeoutInstance); 3090 writeTimeoutInstance = setTimeout(function() { 3091 target(value); 3092 }, timeout); 3093 } 3094 }); 3095 }, 3096 3097 'notify': function(target, notifyWhen) { 3098 target["equalityComparer"] = notifyWhen == "always" 3099 ? function() { return false } // Treat all values as not equal
3100 : ko.observable["fn"]["equalityComparer"]; 3101 return target; 3102 } 3103}; 3104 3105function applyExtenders(requestedExtenders) { 3106 var target = this; 3107 if (requestedExtenders) { 3108 ko.utils.objectForEach(requestedExtenders, function(key, value) { 3109 var extenderHandler = ko.extenders[key]; 3110 if (typeof extenderHandler == 'function') { 3111 target = extenderHandler(target, value); 3112 } 3113 }); 3114 } 3115 return target; 3116} 3117 3118ko.exportSymbol('extenders', ko.extenders); 3119 3120ko.subscription = function (target, callback, disposeCallback) { 3121 this.target = target; 3122 this.callback = callback; 3123 this.disposeCallback = disposeCallback; 3124 ko.exportProperty(this, 'dispose', this.dispose); 3125}; 3126ko.subscription.prototype.dispose = function () { 3127 this.isDisposed = true; 3128 this.disposeCallback(); 3129}; 3130 3131ko.subscribable = function () { 3132 this._subscriptions = {}; 3133 3134 ko.utils.extend(this, ko.subscribable['fn']); 3135 ko.exportProperty(this, 'subscribe', this.subscribe); 3136 ko.exportProperty(this, 'extend', this.extend); 3137 ko.exportProperty(this, 'getSubscriptionsCount', this.getSubscriptionsCount); 3138} 3139 3140var defaultEvent = "change"; 3141 3142ko.subscribable['fn'] = { 3143 subscribe: function (callback, callbackTarget, event) { 3144 event = event || defaultEvent; 3145 var boundCallback = callbackTarget ? callback.bind(callbackTarget) : callback; 3146 3147 var subscription = new ko.subscription(this, boundCallback, function () { 3148 ko.utils.arrayRemoveItem(this._subscriptions[event], subscription); 3149 }.bind(this)); 3150 3151 if (!this._subscriptions[event]) 3152 this._subscriptions[event] = []; 3153 this._subscriptions[event].push(subscription); 3154 return subscription; 3155 }, 3156 3157 "notifySubscribers": function (valueToNotify, event) { 3158 event = event || defaultEvent; 3159 if (this._subscriptions[event]) { 3160 ko.dependencyDetection.ignore(function() { 3161 ko.utils.arrayForEach(this._subscriptions[event].slice(0), function (subscription) { 3162 // In case a subscription was disposed during the arrayForEach cycle, check 3163 // for isDisposed on each subscription before invoking its callback 3164 if (subscription && (subscription.isDisposed !== true)) 3165 subscription.callback(valueToNotify); 3166 }); 3167 }, this); 3168 } 3169 }, 3170 3171 getSubscriptionsCount: function () { 3172 var total = 0; 3173 ko.utils.objectForEach(this._subscriptions, function(eventName, subscriptions) { 3174 total += subscriptions.length; 3175 }); 3176 return total; 3177 }, 3178 3179 extend: applyExtenders 3180}; 3181 3182 3183ko.isSubscribable = function (instance) { 3184 return instance != null && typeof instance.subscribe == "function" && typeof instance["notifySubscribers"] == "function"; 3185}; 3186 3187ko.exportSymbol('subscribable', ko.subscribable); 3188ko.exportSymbol('isSubscribable', ko.isSubscribable); 3189 3190ko.dependencyDetection = (function () { 3191 var _frames = []; 3192 3193 return { 3194 begin: function (callback) { 3195 _frames.push({ callback: callback, distinctDependencies:[] }); 3196 }, 3197 3198 end: function () { 3199 _frames.pop(); 3200 }, 3201 3202 registerDependency: function (subscribable) { 3203 if (!ko.isSubscribable(subscribable)) 3204 throw new Error("Only subscribable things can act as dependencies"); 3205 if (_frames.length > 0) { 3206 var topFrame = _frames[_frames.length - 1]; 3207 if (!topFrame || ko.utils.arrayIndexOf(topFrame.distinctDependencies, subscribable) >= 0) 3208 return; 3209 topFrame.distinctDependencies.push(subscribable); 3210 topFrame.callback(subscribable); 3211 } 3212 }, 3213 3214 ignore: function(callback, callbackTarget, callbackArgs) { 3215 try { 3216 _frames.push(null); 3217 return callback.apply(callbackTarget, callbackArgs || []); 3218 } finally { 3219 _frames.pop(); 3220 } 3221 } 3222 }; 3223})(); 3224var primitiveTypes = { 'undefined':true, 'boolean':true, 'number':true, 'string':true }; 3225 3226ko.observable = function (initialValue) { 3227 var _latestValue = initialValue; 3228 3229 function observable() { 3230 if (arguments.length > 0) { 3231 // Write 3232 3233 // Ignore writes if the value hasn't changed 3234 if ((!observable['equalityComparer']) || !observable['equalityComparer'](_latestValue, arguments[0])) { 3235 observable.valueWillMutate(); 3236 _latestValue = arguments[0]; 3237 if (DEBUG) observable._latestValue = _latestValue; 3238 observable.valueHasMutated(); 3239 } 3240 return this; // Permits chained assignments 3241 } 3242 else { 3243 // Read 3244 ko.dependencyDetection.registerDependency(observable); // The caller only needs to be notified of changes if they did a "read" operation 3245 return _latestValue; 3246 } 3247 } 3248 if (DEBUG) observable._latestValue = _latestValue; 3249 ko.subscribable.call(observable); 3250 observable.peek = function() { return _latestValue }; 3251 observable.valueHasMutated = function () { observable["notifySubscribers"](_latestValue); } 3252 observable.valueWillMutate = function () { observable["notifySubscribers"](_latestValue, "beforeChange"); } 3253 ko.utils.extend(observable, ko.observable['fn']); 3254
3255 ko.exportProperty(observable, 'peek', observable.peek); 3256 ko.exportProperty(observable, "valueHasMutated", observable.valueHasMutated); 3257 ko.exportProperty(observable, "valueWillMutate", observable.valueWillMutate); 3258 3259 return observable; 3260} 3261 3262ko.observable['fn'] = { 3263 "equalityComparer": function valuesArePrimitiveAndEqual(a, b) { 3264 var oldValueIsPrimitive = (a === null) || (typeof(a) in primitiveTypes); 3265 return oldValueIsPrimitive ? (a === b) : false; 3266 } 3267}; 3268 3269var protoProperty = ko.observable.protoProperty = "__ko_proto__"; 3270ko.observable['fn'][protoProperty] = ko.observable; 3271 3272ko.hasPrototype = function(instance, prototype) { 3273 if ((instance === null) || (instance === undefined) || (instance[protoProperty] === undefined)) return false; 3274 if (instance[protoProperty] === prototype) return true; 3275 return ko.hasPrototype(instance[protoProperty], prototype); // Walk the prototype chain 3276}; 3277 3278ko.isObservable = function (instance) { 3279 return ko.hasPrototype(instance, ko.observable); 3280} 3281ko.isWriteableObservable = function (instance) { 3282 // Observable 3283 if ((typeof instance == "function") && instance[protoProperty] === ko.observable) 3284 return true; 3285 // Writeable dependent observable 3286 if ((typeof instance == "function") && (instance[protoProperty] === ko.dependentObservable) && (instance.hasWriteFunction)) 3287 return true; 3288 // Anything else 3289 return false; 3290} 3291 3292 3293ko.exportSymbol('observable', ko.observable); 3294ko.exportSymbol('isObservable', ko.isObservable); 3295ko.exportSymbol('isWriteableObservable', ko.isWriteableObservable); 3296ko.observableArray = function (initialValues) { 3297 initialValues = initialValues || []; 3298 3299 if (typeof initialValues != 'object' || !('length' in initialValues)) 3300 throw new Error("The argument passed when initializing an observable array must be an array, or null, or undefined."); 3301 3302 var result = ko.observable(initialValues); 3303 ko.utils.extend(result, ko.observableArray['fn']); 3304 return result; 3305}; 3306 3307ko.observableArray['fn'] = { 3308 'remove': function (valueOrPredicate) { 3309 var underlyingArray = this.peek(); 3310 var removedValues = []; 3311 var predicate = typeof valueOrPredicate == "function" ? valueOrPredicate : function (value) { return value === valueOrPredicate; }; 3312 for (var i = 0; i < underlyingArray.length; i++) { 3313 var value = underlyingArray[i]; 3314 if (predicate(value)) { 3315 if (removedValues.length === 0) { 3316 this.valueWillMutate(); 3317 } 3318 removedValues.push(value); 3319 underlyingArray.splice(i, 1); 3320 i--; 3321 } 3322 } 3323 if (removedValues.length) { 3324 this.valueHasMutated(); 3325 } 3326 return removedValues; 3327 }, 3328 3329 'removeAll': function (arrayOfValues) { 3330 // If you passed zero args, we remove everything 3331 if (arrayOfValues === undefined) { 3332 var underlyingArray = this.peek(); 3333 var allValues = underlyingArray.slice(0); 3334 this.valueWillMutate(); 3335 underlyingArray.splice(0, underlyingArray.length); 3336 this.valueHasMutated(); 3337 return allValues; 3338 } 3339 // If you passed an arg, we interpret it as an array of entries to remove 3340 if (!arrayOfValues) 3341 return []; 3342 return this['remove'](function (value) { 3343 return ko.utils.arrayIndexOf(arrayOfValues, value) >= 0; 3344 }); 3345 }, 3346 3347 'destroy': function (valueOrPredicate) { 3348 var underlyingArray = this.peek(); 3349 var predicate = typeof valueOrPredicate == "function" ? valueOrPredicate : function (value) { return value === valueOrPredicate; }; 3350 this.valueWillMutate(); 3351 for (var i = underlyingArray.length - 1; i >= 0; i--) { 3352 var value = underlyingArray[i]; 3353 if (predicate(value)) 3354 underlyingArray[i]["_destroy"] = true; 3355 } 3356 this.valueHasMutated(); 3357 }, 3358 3359 'destroyAll': function (arrayOfValues) { 3360 // If you passed zero args, we destroy everything 3361 if (arrayOfValues === undefined) 3362 return this['destroy'](function() { return true });
3363 3364 // If you passed an arg, we interpret it as an array of entries to destroy 3365 if (!arrayOfValues) 3366 return []; 3367 return this['destroy'](function (value) { 3368 return ko.utils.arrayIndexOf(arrayOfValues, value) >= 0; 3369 }); 3370 }, 3371 3372 'indexOf': function (item) { 3373 var underlyingArray = this(); 3374 return ko.utils.arrayIndexOf(underlyingArray, item); 3375 }, 3376 3377 'replace': function(oldItem, newItem) { 3378 var index = this['indexOf'](oldItem); 3379 if (index >= 0) { 3380 this.valueWillMutate(); 3381 this.peek()[index] = newItem; 3382 this.valueHasMutated(); 3383 } 3384 } 3385}; 3386 3387// Populate ko.observableArray.fn with read/write functions from native arrays 3388// Important: Do not add any additional functions here that may reasonably be used to *read* data from the array 3389// because we'll eval them without causing subscriptions, so ko.computed output could end up getting stale 3390ko.utils.arrayForEach(["pop", "push", "reverse", "shift", "sort", "splice", "unshift"], function (methodName) { 3391 ko.observableArray['fn'][methodName] = function () { 3392 // Use "peek" to avoid creating a subscription in any computed that we're executing in the context of 3393 // (for consistency with mutating regular observables) 3394 var underlyingArray = this.peek(); 3395 this.valueWillMutate(); 3396 var methodCallResult = underlyingArray[methodName].apply(underlyingArray, arguments); 3397 this.valueHasMutated(); 3398 return methodCallResult; 3399 }; 3400}); 3401 3402// Populate ko.observableArray.fn with read-only functions from native arrays 3403ko.utils.arrayForEach(["slice"], function (methodName) { 3404 ko.observableArray['fn'][methodName] = function () { 3405 var underlyingArray = this(); 3406 return underlyingArray[methodName].apply(underlyingArray, arguments); 3407 }; 3408}); 3409 3410ko.exportSymbol('observableArray', ko.observableArray); 3411ko.dependentObservable = function (evaluatorFunctionOrOptions, evaluatorFunctionTarget, options) { 3412 var _latestValue, 3413 _hasBeenEvaluated = false, 3414 _isBeingEvaluated = false, 3415 readFunction = evaluatorFunctionOrOptions; 3416 3417 if (readFunction && typeof readFunction == "object") { 3418 // Single-parameter syntax - everything is on this "options" param 3419 options = readFunction; 3420 readFunction = options["read"]; 3421 } else { 3422 // Multi-parameter syntax - construct the options according to the params passed 3423 options = options || {}; 3424 if (!readFunction) 3425 readFunction = options["read"]; 3426 } 3427 if (typeof readFunction != "function") 3428 throw new Error("Pass a function that returns the value of the ko.computed"); 3429 3430 function addSubscriptionToDependency(subscribable) { 3431 _subscriptionsToDependencies.push(subscribable.subscribe(evaluatePossiblyAsync)); 3432 } 3433 3434 function disposeAllSubscriptionsToDependencies() { 3435 ko.utils.arrayForEach(_subscriptionsToDependencies, function (subscription) { 3436 subscription.dispose(); 3437 }); 3438 _subscriptionsToDependencies = []; 3439 } 3440 3441 function evaluatePossiblyAsync() { 3442 var throttleEvaluationTimeout = dependentObservable['throttleEvaluation']; 3443 if (throttleEvaluationTimeout && throttleEvaluationTimeout >= 0) { 3444 clearTimeout(evaluationTimeoutInstance); 3445 evaluationTimeoutInstance = setTimeout(evaluateImmediate, throttleEvaluationTimeout); 3446 } else 3447 evaluateImmediate(); 3448 } 3449 3450 function evaluateImmediate() { 3451 if (_isBeingEvaluated) { 3452 // If the evaluation of a ko.computed causes side effects, it's possible that it will trigger its own re-evaluation. 3453 // This is not desirable (it's hard for a developer to realise a chain of dependencies might cause this, and they almost 3454 // certainly didn't intend infinite re-evaluations). So, for predictability, we simply prevent ko.computeds from causing 3455 // their own re-evaluation. Further discussion at https://github.com/SteveSanderson/knockout/pull/387 3456 return; 3457 } 3458 3459 // Don't dispose on first evaluation, because the "disposeWhen" callback might 3460 // e.g., dispose when the associated DOM element isn't in the doc, and it's not 3461 // going to be in the doc until *after* the first evaluation 3462 if (_hasBeenEvaluated && disposeWhen()) { 3463 dispose(); 3464 return; 3465 } 3466 3467 _isBeingEvaluated = true; 3468 try { 3469 // Initially, we assume that none of the subscriptions are still being used (i.e., all are candidates for disposal). 3470 // Then, during evaluation, we cross off any that are in fact still being used. 3471 var disposalCandidates = ko.utils.arrayMap(_subscriptionsToDependencies, function(item) {return item.target;}); 3472 3473 ko.dependencyDetection.begin(function(subscribable) { 3474 var inOld; 3475 if ((inOld = ko.utils.arrayIndexOf(disposalCandidates, subscribable)) >= 0) 3476 disposalCandidates[inOld] = undefined; // Don't want to dispose this subscription, as it's still being used 3477 else 3478 addSubscriptionToDependency(subscribable); // Brand new subscription - add it 3479 }); 3480 3481 var newValue = readFunction.call(evaluatorFunctionTarget); 3482 3483 // For each subscription no longer being used, remove it from the active subscriptions list and dispose it 3484 for (var i = disposalCandidates.length - 1; i >= 0; i--) { 3485 if (disposalCandidates[i]) 3486 _subscriptionsToDependencies.splice(i, 1)[0].dispose(); 3487 } 3488 _hasBeenEvaluated = true; 3489 3490 dependentObservable["notifySubscribers"](_latestValue, "beforeChange"); 3491 3492 _latestValue = newValue; 3493 if (DEBUG) dependentObservable._latestValue = _latestValue; 3494 dependentObservable["notifySubscribers"](_latestValue); 3495 3496 } finally { 3497 ko.dependencyDetection.end(); 3498 _isBeingEvaluated = false; 3499 } 3500 3501 if (!_subscriptionsToDependencies.length) 3502 dispose(); 3503 } 3504 3505 function dependentObservable() { 3506 if (arguments.length > 0) { 3507 if (typeof writeFunction === "function") { 3508 // Writing a value 3509 writeFunction.apply(evaluatorFunctionTarget, arguments); 3510 } else { 3511 throw new Error("Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters."); 3512 } 3513 return this; // Permits chained assignments 3514 } else { 3515 // Reading the value 3516 if (!_hasBeenEvaluated) 3517 evaluateImmediate(); 3518 ko.dependencyDetection.registerDependency(dependentObservable); 3519 return _latestValue; 3520 } 3521 } 3522 3523 function peek() { 3524 if (!_hasBeenEvaluated) 3525 evaluateImmediate(); 3526 return _latestValue; 3527 } 3528 3529 function isActive() { 3530 return !_hasBeenEvaluated || _subscriptionsToDependencies.length > 0;
3531 } 3532 3533 // By here, "options" is always non-null 3534 var writeFunction = options["write"], 3535 disposeWhenNodeIsRemoved = options["disposeWhenNodeIsRemoved"] || options.disposeWhenNodeIsRemoved || null, 3536 disposeWhen = options["disposeWhen"] || options.disposeWhen || function() { return false; }, 3537 dispose = disposeAllSubscriptionsToDependencies, 3538 _subscriptionsToDependencies = [], 3539 evaluationTimeoutInstance = null; 3540 3541 if (!evaluatorFunctionTarget) 3542 evaluatorFunctionTarget = options["owner"]; 3543 3544 dependentObservable.peek = peek; 3545 dependentObservable.getDependenciesCount = function () { return _subscriptionsToDependencies.length; }; 3546 dependentObservable.hasWriteFunction = typeof options["write"] === "function"; 3547 dependentObservable.dispose = function () { dispose(); }; 3548 dependentObservable.isActive = isActive; 3549 3550 ko.subscribable.call(dependentObservable); 3551 ko.utils.extend(dependentObservable, ko.dependentObservable['fn']); 3552 3553 ko.exportProperty(dependentObservable, 'peek', dependentObservable.peek); 3554 ko.exportProperty(dependentObservable, 'dispose', dependentObservable.dispose); 3555 ko.exportProperty(dependentObservable, 'isActive', dependentObservable.isActive); 3556 ko.exportProperty(dependentObservable, 'getDependenciesCount', dependentObservable.getDependenciesCount); 3557 3558 // Evaluate, unless deferEvaluation is true 3559 if (options['deferEvaluation'] !== true) 3560 evaluateImmediate(); 3561 3562 // Build "disposeWhenNodeIsRemoved" and "disposeWhenNodeIsRemovedCallback" option values. 3563 // But skip if isActive is false (there will never be any dependencies to dispose). 3564 // (Note: "disposeWhenNodeIsRemoved" option both proactively disposes as soon as the node is removed using ko.removeNode(), 3565 // plus adds a "disposeWhen" callback that, on each evaluation, disposes if the node was removed by some other means.) 3566 if (disposeWhenNodeIsRemoved && isActive()) { 3567 dispose = function() { 3568 ko.utils.domNodeDisposal.removeDisposeCallback(disposeWhenNodeIsRemoved, dispose); 3569 disposeAllSubscriptionsToDependencies(); 3570 }; 3571 ko.utils.domNodeDisposal.addDisposeCallback(disposeWhenNodeIsRemoved, dispose); 3572 var existingDisposeWhenFunction = disposeWhen; 3573 disposeWhen = function () { 3574 return !ko.utils.domNodeIsAttachedToDocument(disposeWhenNodeIsRemoved) || existingDisposeWhenFunction(); 3575 } 3576 } 3577 3578 return dependentObservable; 3579}; 3580 3581ko.isComputed = function(instance) { 3582 return ko.hasPrototype(instance, ko.dependentObservable); 3583}; 3584 3585var protoProp = ko.observable.protoProperty; // == "__ko_proto__" 3586ko.dependentObservable[protoProp] = ko.observable; 3587 3588ko.dependentObservable['fn'] = {}; 3589ko.dependentObservable['fn'][protoProp] = ko.dependentObservable; 3590 3591ko.exportSymbol('dependentObservable', ko.dependentObservable); 3592ko.exportSymbol('computed', ko.dependentObservable); // Make "ko.computed" an alias for "ko.dependentObservable" 3593ko.exportSymbol('isComputed', ko.isComputed); 3594 3595(function() { 3596 var maxNestedObservableDepth = 10; // Escape the (unlikely) pathalogical case where an observable's current value is itself (or similar reference cycle) 3597 3598 ko.toJS = function(rootObject) { 3599 if (arguments.length == 0) 3600 throw new Error("When calling ko.toJS, pass the object you want to convert."); 3601 3602 // We just unwrap everything at every level in the object graph 3603 return mapJsObjectGraph(rootObject, function(valueToMap) { 3604 // Loop because an observable's value might in turn be another observable wrapper 3605 for (var i = 0; ko.isObservable(valueToMap) && (i < maxNestedObservableDepth); i++) 3606 valueToMap = valueToMap(); 3607 return valueToMap; 3608 }); 3609 }; 3610 3611 ko.toJSON = function(rootObject, replacer, space) { // replacer and space are optional 3612 var plainJavaScriptObject = ko.toJS(rootObject); 3613 return ko.utils.stringifyJson(plainJavaScriptObject, replacer, space); 3614 }; 3615 3616 function mapJsObjectGraph(rootObject, mapInputCallback, visitedObjects) { 3617 visitedObjects = visitedObjects || new objectLookup(); 3618 3619 rootObject = mapInputCallback(rootObject); 3620 var canHaveProperties = (typeof rootObject == "object") && (rootObject !== null) && (rootObject !== undefined) && (!(rootObject instanceof Date)) && (!(rootObject instanceof String)) && (!(rootObject instanceof Number)) && (!(rootObject instanceof Boolean)); 3621 if (!canHaveProperties) 3622 return rootObject; 3623 3624 var outputProperties = rootObject instanceof Array ? [] : {}; 3625 visitedObjects.save(rootObject, outputProperties); 3626 3627 visitPropertiesOrArrayEntries(rootObject, function(indexer) { 3628 var propertyValue = mapInputCallback(rootObject[indexer]); 3629 3630 switch (typeof propertyValue) { 3631 case "boolean": 3632 case "number": 3633 case "string": 3634 case "function": 3635 outputProperties[indexer] = propertyValue; 3636 break; 3637 case "object": 3638 case "undefined": 3639 var previouslyMappedValue = visitedObjects.get(propertyValue); 3640 outputProperties[indexer] = (previouslyMappedValue !== undefined) 3641 ? previouslyMappedValue 3642 : mapJsObjectGraph(propertyValue, mapInputCallback, visitedObjects); 3643 break; 3644 } 3645 }); 3646 3647 return outputProperties; 3648 } 3649 3650 function visitPropertiesOrArrayEntries(rootObject, visitorCallback) { 3651 if (rootObject instanceof Array) { 3652 for (var i = 0; i < rootObject.length; i++) 3653 visitorCallback(i); 3654 3655 // For arrays, also respect toJSON property for custom mappings (fixes #278) 3656 if (typeof rootObject['toJSON'] == 'function') 3657 visitorCallback('toJSON'); 3658 } else { 3659 for (var propertyName in rootObject) { 3660 visitorCallback(propertyName); 3661 } 3662 } 3663 }; 3664 3665 function objectLookup() { 3666 this.keys = []; 3667 this.values = []; 3668 }; 3669 3670 objectLookup.prototype = { 3671 constructor: objectLookup, 3672 save: function(key, value) { 3673 var existingIndex = ko.utils.arrayIndexOf(this.keys, key); 3674 if (existingIndex >= 0) 3675 this.values[existingIndex] = value; 3676 else { 3677 this.keys.push(key); 3678 this.values.push(value); 3679 } 3680 }, 3681 get: function(key) { 3682 var existingIndex = ko.utils.arrayIndexOf(this.keys, key); 3683 return (existingIndex >= 0) ? this.values[existingIndex] : undefined; 3684 } 3685 }; 3686})(); 3687 3688ko.exportSymbol('toJS', ko.toJS); 3689ko.exportSymbol('toJSON', ko.toJSON); 3690(function () { 3691 var hasDomDataExpandoProperty = '__ko__hasDomDataOptionValue__'; 3692 3693 // Normally, SELECT elements and their OPTIONs can only take value of type 'string' (because the values 3694 // are stored on DOM attributes). ko.selectExtensions provides a way for SELECTs/OPTIONs to have values 3695 // that are arbitrary objects. This is very convenient when implementing things like cascading dropdowns. 3696 ko.selectExtensions = { 3697 readValue : function(element) { 3698 switch (ko.utils.tagNameLower(element)) { 3699 case 'option': 3700 if (element[hasDomDataExpandoProperty] === true) 3701 return ko.utils.domData.get(element, ko.bindingHandlers.options.optionValueDomDataKey); 3702 return ko.utils.ieVersion <= 7 3703 ? (element.getAttributeNode('value') && element.getAttributeNode('value').specified ? element.value : element.text) 3704 : element.value; 3705 case 'select': 3706 return element.selectedIndex >= 0 ? ko.selectExtensions.readValue(element.options[element.selectedIndex]) : undefined; 3707 default: 3708 return element.value; 3709 } 3710 }, 3711 3712 writeValue: function(element, value) { 3713 switch (ko.utils.tagNameLower(element)) { 3714 case 'option': 3715 switch(typeof value) { 3716 case "string": 3717 ko.utils.domData.set(element, ko.bindingHandlers.options.optionValueDomDataKey, undefined); 3718 if (hasDomDataExpandoProperty in element) { // IE <= 8 throws errors if you delete non-existent properties from a DOM node 3719 delete element[hasDomDataExpandoProperty]; 3720 } 3721 element.value = value; 3722 break; 3723 default: 3724 // Store arbitrary object using DomData 3725 ko.utils.domData.set(element, ko.bindingHandlers.options.optionValueDomDataKey, value); 3726 element[hasDomDataExpandoProperty] = true; 3727 3728 // Special treatment of numbers is just for backward compatibility. KO 1.2.1 wrote numerical values to element.value. 3729 element.value = typeof value === "number" ? value : ""; 3730 break; 3731 } 3732 break; 3733 case 'select': 3734 if (value === "") 3735 value = undefined; 3736 if (value === null || value === undefined) 3737 element.selectedIndex = -1; 3738 for (var i = element.options.length - 1; i >= 0; i--) { 3739 if (ko.selectExtensions.readValue(element.options[i]) == value) { 3740 element.selectedIndex = i; 3741 break; 3742 } 3743 } 3744 // for drop-down select, ensure first is selected 3745 if (!(element.size > 1) && element.selectedIndex === -1) { 3746 element.selectedIndex = 0; 3747 } 3748 break; 3749 default: 3750 if ((value === null) || (value === undefined)) 3751 value = ""; 3752 element.value = value; 3753 break; 3754 } 3755 } 3756 }; 3757})(); 3758 3759ko.exportSymbol('selectExtensions', ko.selectExtensions); 3760ko.exportSymbol('selectExtensions.readValue', ko.selectExtensions.readValue); 3761ko.exportSymbol('selectExtensions.writeValue', ko.selectExtensions.writeValue); 3762ko.expressionRewriting = (function () { 3763 var restoreCapturedTokensRegex = /\@ko_token_(\d+)\@/g; 3764 var javaScriptReservedWords = ["true", "false", "null", "undefined"]; 3765 3766 // Matches something that can be assigned to--either an isolated identifier or something ending with a property accessor 3767 // This is designed to be simple and avoid false negatives, but could produce false positives (e.g., a+b.c). 3768 var javaScriptAssignmentTarget = /^(?:[$_a-z][$\w]*|(.+)(\.\s*[$_a-z][$\w]*|\[.+\]))$/i; 3769 3770 function restoreTokens(string, tokens) { 3771 var prevValue = null; 3772 while (string != prevValue) { // Keep restoring tokens until it no longer makes a difference (they may be nested) 3773 prevValue = string;
3774 string = string.replace(restoreCapturedTokensRegex, function (match, tokenIndex) { 3775 return tokens[tokenIndex]; 3776 }); 3777 } 3778 return string; 3779 } 3780 3781 function getWriteableValue(expression) { 3782 if (ko.utils.arrayIndexOf(javaScriptReservedWords, ko.utils.stringTrim(expression).toLowerCase()) >= 0) 3783 return false; 3784 var match = expression.match(javaScriptAssignmentTarget); 3785 return match === null ? false : match[1] ? ('Object(' + match[1] + ')' + match[2]) : expression; 3786 } 3787 3788 function ensureQuoted(key) { 3789 var trimmedKey = ko.utils.stringTrim(key); 3790 switch (trimmedKey.length && trimmedKey.charAt(0)) { 3791 case "'": 3792 case '"': 3793 return key; 3794 default: 3795 return "'" + trimmedKey + "'"; 3796 } 3797 } 3798 3799 return { 3800 bindingRewriteValidators: [], 3801 3802 parseObjectLiteral: function(objectLiteralString) { 3803 // A full tokeniser+lexer would add too much weight to this library, so here's a simple parser 3804 // that is sufficient just to split an object literal string into a set of top-level key-value pairs 3805 3806 var str = ko.utils.stringTrim(objectLiteralString); 3807 if (str.length < 3) 3808 return []; 3809 if (str.charAt(0) === "{")// Ignore any braces surrounding the whole object literal 3810 str = str.substring(1, str.length - 1); 3811 3812 // Pull out any string literals and regex literals 3813 var tokens = []; 3814 var tokenStart = null, tokenEndChar; 3815 for (var position = 0; position < str.length; position++) { 3816 var c = str.charAt(position); 3817 if (tokenStart === null) { 3818 switch (c) { 3819 case '"': 3820 case "'": 3821 case "/": 3822 tokenStart = position; 3823 tokenEndChar = c; 3824 break; 3825 } 3826 } else if ((c == tokenEndChar) && (str.charAt(position - 1) !== "\\")) { 3827 var token = str.substring(tokenStart, position + 1); 3828 tokens.push(token); 3829 var replacement = "@ko_token_" + (tokens.length - 1) + "@"; 3830 str = str.substring(0, tokenStart) + replacement + str.substring(position + 1); 3831 position -= (token.length - replacement.length); 3832 tokenStart = null; 3833 } 3834 } 3835 3836 // Next pull out balanced paren, brace, and bracket blocks 3837 tokenStart = null; 3838 tokenEndChar = null; 3839 var tokenDepth = 0, tokenStartChar = null; 3840 for (var position = 0; position < str.length; position++) { 3841 var c = str.charAt(position); 3842 if (tokenStart === null) { 3843 switch (c) { 3844 case "{": tokenStart = position; tokenStartChar = c; 3845 tokenEndChar = "}"; 3846 break; 3847 case "(": tokenStart = position; tokenStartChar = c; 3848 tokenEndChar = ")"; 3849 break; 3850 case "[": tokenStart = position; tokenStartChar = c; 3851 tokenEndChar = "]"; 3852 break; 3853 } 3854 } 3855 3856 if (c === tokenStartChar) 3857 tokenDepth++; 3858 else if (c === tokenEndChar) { 3859 tokenDepth--; 3860 if (tokenDepth === 0) { 3861 var token = str.substring(tokenStart, position + 1); 3862 tokens.push(token); 3863 var replacement = "@ko_token_" + (tokens.length - 1) + "@"; 3864 str = str.substring(0, tokenStart) + replacement + str.substring(position + 1); 3865 position -= (token.length - replacement.length); 3866 tokenStart = null; 3867 } 3868 } 3869 } 3870 3871 // Now we can safely split on commas to get the key/value pairs 3872 var result = []; 3873 var keyValuePairs = str.split(","); 3874 for (var i = 0, j = keyValuePairs.length; i < j; i++) { 3875 var pair = keyValuePairs[i]; 3876 var colonPos = pair.indexOf(":"); 3877 if ((colonPos > 0) && (colonPos < pair.length - 1)) { 3878 var key = pair.substring(0, colonPos); 3879 var value = pair.substring(colonPos + 1); 3880 result.push({ 'key': restoreTokens(key, tokens), 'value': restoreTokens(value, tokens) }); 3881 } else { 3882 result.push({ 'unknown': restoreTokens(pair, tokens) }); 3883 } 3884 } 3885 return result; 3886 }, 3887 3888 preProcessBindings: function (objectLiteralStringOrKeyValueArray) { 3889 var keyValueArray = typeof objectLiteralStringOrKeyValueArray === "string" 3890 ? ko.expressionRewriting.parseObjectLiteral(objectLiteralStringOrKeyValueArray) 3891 : objectLiteralStringOrKeyValueArray; 3892 var resultStrings = [], propertyAccessorResultStrings = []; 3893 3894 var keyValueEntry; 3895 for (var i = 0; keyValueEntry = keyValueArray[i]; i++) { 3896 if (resultStrings.length > 0) 3897 resultStrings.push(","); 3898 3899 if (keyValueEntry['key']) { 3900 var quotedKey = ensureQuoted(keyValueEntry['key']), val = keyValueEntry['value']; 3901 resultStrings.push(quotedKey); 3902 resultStrings.push(":"); 3903 resultStrings.push(val); 3904 3905 if (val = getWriteableValue(ko.utils.stringTrim(val))) { 3906 if (propertyAccessorResultStrings.length > 0) 3907 propertyAccessorResultStrings.push(", "); 3908 propertyAccessorResultStrings.push(quotedKey + " : function(__ko_value) { " + val + " = __ko_value; }"); 3909 } 3910 } else if (keyValueEntry['unknown']) { 3911 resultStrings.push(keyValueEntry['unknown']); 3912 } 3913 } 3914 3915 var combinedResult = resultStrings.join(""); 3916 if (propertyAccessorResultStrings.length > 0) { 3917 var allPropertyAccessors = propertyAccessorResultStrings.join("");
3918 combinedResult = combinedResult + ", '_ko_property_writers' : { " + allPropertyAccessors + " } "; 3919 } 3920 3921 return combinedResult; 3922 }, 3923 3924 keyValueArrayContainsKey: function(keyValueArray, key) { 3925 for (var i = 0; i < keyValueArray.length; i++) 3926 if (ko.utils.stringTrim(keyValueArray[i]['key']) == key) 3927 return true; 3928 return false; 3929 }, 3930 3931 // Internal, private KO utility for updating model properties from within bindings 3932 // property: If the property being updated is (or might be) an observable, pass it here 3933 // If it turns out to be a writable observable, it will be written to directly 3934 // allBindingsAccessor: All bindings in the current execution context. 3935 // This will be searched for a '_ko_property_writers' property in case you're writing to a non-observable 3936 // key: The key identifying the property to be written. Example: for { hasFocus: myValue }, write to 'myValue' by specifying the key 'hasFocus' 3937 // value: The value to be written 3938 // checkIfDifferent: If true, and if the property being written is a writable observable, the value will only be written if 3939 // it is !== existing value on that writable observable 3940 writeValueToProperty: function(property, allBindingsAccessor, key, value, checkIfDifferent) { 3941 if (!property || !ko.isObservable(property)) { 3942 var propWriters = allBindingsAccessor()['_ko_property_writers']; 3943 if (propWriters && propWriters[key]) 3944 propWriters[key](value); 3945 } else if (ko.isWriteableObservable(property) && (!checkIfDifferent || property.peek() !== value)) { 3946 property(value); 3947 } 3948 } 3949 }; 3950})(); 3951 3952ko.exportSymbol('expressionRewriting', ko.expressionRewriting); 3953ko.exportSymbol('expressionRewriting.bindingRewriteValidators', ko.expressionRewriting.bindingRewriteValidators); 3954ko.exportSymbol('expressionRewriting.parseObjectLiteral', ko.expressionRewriting.parseObjectLiteral); 3955ko.exportSymbol('expressionRewriting.preProcessBindings', ko.expressionRewriting.preProcessBindings); 3956 3957// For backward compatibility, define the following aliases. (Previously, these function names were misleading because 3958// they referred to JSON specifically, even though they actually work with arbitrary JavaScript object literal expressions.) 3959ko.exportSymbol('jsonExpressionRewriting', ko.expressionRewriting); 3960ko.exportSymbol('jsonExpressionRewriting.insertPropertyAccessorsIntoJson', ko.expressionRewriting.preProcessBindings);(function() { 3961 // "Virtual elements" is an abstraction on top of the usual DOM API which understands the notion that comment nodes 3962 // may be used to represent hierarchy (in addition to the DOM's natural hierarchy). 3963 // If you call the DOM-manipulating functions on ko.virtualElements, you will be able to read and write the state 3964 // of that virtual hierarchy 3965 // 3966 // The point of all this is to support containerless templates (e.g., <!-- ko foreach:someCollection -->blah<!-- /ko -->) 3967 // without having to scatter special cases all over the binding and templating code. 3968 3969 // IE 9 cannot reliably read the "nodeValue" property of a comment node (see https://github.com/SteveSanderson/knockout/issues/186) 3970 // but it does give them a nonstandard alternative property called "text" that it can read reliably. Other browsers don't have that property. 3971 // So, use node.text where available, and node.nodeValue elsewhere 3972 var commentNodesHaveTextProperty = document && document.createComment("test").text === "<!--test-->"; 3973 3974 var startCommentRegex = commentNodesHaveTextProperty ? /^<!--\s*ko(?:\s+(.+\s*\:[\s\S]*))?\s*-->$/ : /^\s*ko(?:\s+(.+\s*\:[\s\S]*))?\s*$/; 3975 var endCommentRegex = commentNodesHaveTextProperty ? /^<!--\s*\/ko\s*-->$/ : /^\s*\/ko\s*$/; 3976 var htmlTagsWithOptionallyClosingChildren = { 'ul': true, 'ol': true }; 3977 3978 function isStartComment(node) { 3979 return (node.nodeType == 8) && (commentNodesHaveTextProperty ? node.text : node.nodeValue).match(startCommentRegex); 3980 } 3981 3982 function isEndComment(node) { 3983 return (node.nodeType == 8) && (commentNodesHaveTextProperty ? node.text : node.nodeValue).match(endCommentRegex); 3984 } 3985 3986 function getVirtualChildren(startComment, allowUnbalanced) { 3987 var currentNode = startComment; 3988 var depth = 1; 3989 var children = []; 3990 while (currentNode = currentNode.nextSibling) { 3991 if (isEndComment(currentNode)) { 3992 depth--; 3993 if (depth === 0) 3994 return children; 3995 } 3996 3997 children.push(currentNode); 3998 3999 if (isStartComment(currentNode)) 4000 depth++; 4001 } 4002 if (!allowUnbalanced) 4003 throw new Error("Cannot find closing comment tag to match: " + startComment.
vendor: 4,194 bytes, lines 4003-4088
4003nodeValue); 4004 return null; 4005 } 4006 4007 function getMatchingEndComment(startComment, allowUnbalanced) { 4008 var allVirtualChildren = getVirtualChildren(startComment, allowUnbalanced); 4009 if (allVirtualChildren) { 4010 if (allVirtualChildren.length > 0) 4011 return allVirtualChildren[allVirtualChildren.length - 1].nextSibling; 4012 return startComment.nextSibling; 4013 } else 4014 return null; // Must have no matching end comment, and allowUnbalanced is true 4015 } 4016 4017 function getUnbalancedChildTags(node) { 4018 // e.g., from <div>OK</div><!-- ko blah --><span>Another</span>, returns: <!-- ko blah --><span>Another</span> 4019 // from <div>OK</div><!-- /ko --><!-- /ko -->, returns: <!-- /ko --><!-- /ko --> 4020 var childNode = node.firstChild, captureRemaining = null; 4021 if (childNode) { 4022 do { 4023 if (captureRemaining) // We already hit an unbalanced node and are now just scooping up all subsequent nodes 4024 captureRemaining.push(childNode); 4025 else if (isStartComment(childNode)) { 4026 var matchingEndComment = getMatchingEndComment(childNode, /* allowUnbalanced: */ true); 4027 if (matchingEndComment) // It's a balanced tag, so skip immediately to the end of this virtual set 4028 childNode = matchingEndComment; 4029 else 4030 captureRemaining = [childNode]; // It's unbalanced, so start capturing from this point 4031 } else if (isEndComment(childNode)) { 4032 captureRemaining = [childNode]; // It's unbalanced (if it wasn't, we'd have skipped over it already), so start capturing 4033 } 4034 } while (childNode = childNode.nextSibling); 4035 } 4036 return captureRemaining; 4037 } 4038 4039 ko.virtualElements = { 4040 allowedBindings: {}, 4041 4042 childNodes: function(node) { 4043 return isStartComment(node) ? getVirtualChildren(node) : node.childNodes; 4044 }, 4045 4046 emptyNode: function(node) { 4047 if (!isStartComment(node)) 4048 ko.utils.emptyDomNode(node); 4049 else { 4050 var virtualChildren = ko.virtualElements.childNodes(node); 4051 for (var i = 0, j = virtualChildren.length; i < j; i++) 4052 ko.removeNode(virtualChildren[i]); 4053 } 4054 }, 4055 4056 setDomNodeChildren: function(node, childNodes) { 4057 if (!isStartComment(node)) 4058 ko.utils.setDomNodeChildren(node, childNodes); 4059 else { 4060 ko.virtualElements.emptyNode(node); 4061 var endCommentNode = node.nextSibling; // Must be the next sibling, as we just emptied the children 4062 for (var i = 0, j = childNodes.length; i < j; i++) 4063 endCommentNode.parentNode.insertBefore(childNodes[i], endCommentNode); 4064 } 4065 }, 4066 4067 prepend: function(containerNode, nodeToPrepend) { 4068 if (!isStartComment(containerNode)) { 4069 if (containerNode.firstChild) 4070 containerNode.insertBefore(nodeToPrepend, containerNode.firstChild); 4071 else 4072 containerNode.appendChild(nodeToPrepend); 4073 } else { 4074 // Start comments must always have a parent and at least one following sibling (the end comment) 4075 containerNode.parentNode.insertBefore(nodeToPrepend, containerNode.nextSibling); 4076 } 4077 }, 4078 4079 insertAfter: function(containerNode, nodeToInsert, insertAfterNode) { 4080 if (!insertAfterNode) { 4081 ko.virtualElements.prepend(containerNode, nodeToInsert); 4082 } else if (!isStartComment(containerNode)) { 4083 // Insert after insertion point 4084 if (insertAfterNode.nextSibling) 4085 containerNode.insertBefore(nodeToInsert, insertAfterNode.nextSibling); 4086 else 4087 containerNode.appendChild(nodeToInsert); 4088 } else {
4089 // Children of start comments must always have a parent and at least one following sibling (the end comment) 4090 containerNode.parentNode.insertBefore(nodeToInsert, insertAfterNode.nextSibling); 4091 } 4092 }, 4093 4094 firstChild: function(node) { 4095 if (!isStartComment(node)) 4096 return node.firstChild; 4097 if (!node.nextSibling || isEndComment(node.nextSibling)) 4098 return null; 4099 return node.nextSibling; 4100 }, 4101 4102 nextSibling: function(node) { 4103 if (isStartComment(node)) 4104 node = getMatchingEndComment(node); 4105 if (node.nextSibling && isEndComment(node.nextSibling)) 4106 return null; 4107 return node.nextSibling; 4108 }, 4109 4110 virtualNodeBindingValue: function(node) { 4111 var regexMatch = isStartComment(node); 4112 return regexMatch ? regexMatch[1] : null; 4113 }, 4114 4115 normaliseVirtualElementDomStructure: function(elementVerified) { 4116 // Workaround for https://github.com/SteveSanderson/knockout/issues/155 4117 // (IE <= 8 or IE 9 quirks mode parses your HTML weirdly, treating closing </li> tags as if they don't exist, thereby moving comment nodes 4118 // that are direct descendants of <ul> into the preceding <li>) 4119 if (!htmlTagsWithOptionallyClosingChildren[ko.utils.tagNameLower(elementVerified)]) 4120 return; 4121 4122 // Scan immediate children to see if they contain unbalanced comment tags. If they do, those comment tags 4123 // must be intended to appear *after* that child, so move them there. 4124 var childNode = elementVerified.firstChild; 4125 if (childNode) { 4126 do { 4127 if (childNode.nodeType === 1) { 4128 var unbalancedTags = getUnbalancedChildTags(childNode); 4129 if (unbalancedTags) { 4130 // Fix up the DOM by moving the unbalanced tags to where they most likely were intended to be placed - *after* the child 4131 var nodeToInsertBefore = childNode.nextSibling; 4132 for (var i = 0; i < unbalancedTags.length; i++) { 4133 if (nodeToInsertBefore) 4134 elementVerified.insertBefore(unbalancedTags[i], nodeToInsertBefore); 4135 else 4136 elementVerified.appendChild(unbalancedTags[i]); 4137 } 4138 } 4139 } 4140 } while (childNode = childNode.nextSibling); 4141 } 4142 } 4143 }; 4144})(); 4145ko.exportSymbol('virtualElements', ko.virtualElements); 4146ko.exportSymbol('virtualElements.allowedBindings', ko.virtualElements.allowedBindings); 4147ko.exportSymbol('virtualElements.emptyNode', ko.virtualElements.emptyNode); 4148//ko.exportSymbol('virtualElements.firstChild', ko.virtualElements.firstChild); // firstChild is not minified 4149ko.exportSymbol('virtualElements.insertAfter', ko.virtualElements.insertAfter); 4150//ko.exportSymbol('virtualElements.nextSibling', ko.virtualElements.nextSibling); // nextSibling is not minified 4151ko.exportSymbol('virtualElements.prepend', ko.virtualElements.prepend); 4152ko.exportSymbol('virtualElements.setDomNodeChildren', ko.virtualElements.setDomNodeChildren); 4153(function() { 4154 var defaultBindingAttributeName = "data-bind"; 4155 4156 ko.bindingProvider = function() { 4157 this.bindingCache = {}; 4158 }; 4159 4160 ko.utils.extend(ko.bindingProvider.prototype, { 4161 'nodeHasBindings': function(node) { 4162 switch (node.nodeType) { 4163 case 1: return node.getAttribute(defaultBindingAttributeName) != null; // Element 4164 case 8: return ko.virtualElements.virtualNodeBindingValue(node) != null; // Comment node 4165 default: return false; 4166 } 4167 }, 4168 4169 'getBindings': function(node, bindingContext) { 4170 var bindingsString = this['getBindingsString'](node, bindingContext); 4171 return bindingsString ? this['parseBindingsString'](bindingsString, bindingContext, node) : null; 4172 }, 4173 4174 // The following function is only used internally by this default provider. 4175 // It's not part of the interface definition for a general binding provider. 4176 'getBindingsString': function(node, bindingContext) { 4177 switch (node.nodeType) { 4178 case 1: return node.getAttribute(defaultBindingAttributeName); // Element 4179 case 8: return ko.virtualElements.virtualNodeBindingValue(node); // Comment node 4180 default: return null; 4181 } 4182 }, 4183 4184 // The following function is only used internally by this default provider. 4185 // It's not part of the interface definition for a general binding provider. 4186 'parseBindingsString': function(bindingsString, bindingContext, node) { 4187 try { 4188 var bindingFunction = createBindingsStringEvaluatorViaCache(bindingsString, this.bindingCache); 4189 return bindingFunction(bindingContext, node); 4190 } catch (ex) { 4191 ex.message = "Unable to parse bindings.\nBindings value: " + bindingsString + "\nMessage: " + ex.message; 4192 throw ex; 4193 } 4194 } 4195 });
4196 4197 ko.bindingProvider['instance'] = new ko.bindingProvider(); 4198 4199 function createBindingsStringEvaluatorViaCache(bindingsString, cache) { 4200 var cacheKey = bindingsString; 4201 return cache[cacheKey] 4202 || (cache[cacheKey] = createBindingsStringEvaluator(bindingsString)); 4203 } 4204 4205 function createBindingsStringEvaluator(bindingsString) { 4206 // Build the source for a function that evaluates "expression" 4207 // For each scope variable, add an extra level of "with" nesting 4208 // Example result: with(sc1) { with(sc0) { return (expression) } } 4209 var rewrittenBindings = ko.expressionRewriting.preProcessBindings(bindingsString), 4210 functionBody = "with($context){with($data||{}){return{" + rewrittenBindings + "}}}"; 4211 return new Function("$context", "$element", functionBody); 4212 } 4213})(); 4214 4215ko.exportSymbol('bindingProvider', ko.bindingProvider); 4216(function () { 4217 ko.bindingHandlers = {}; 4218 4219 ko.bindingContext = function(dataItem, parentBindingContext, dataItemAlias) { 4220 if (parentBindingContext) { 4221 ko.utils.extend(this, parentBindingContext); // Inherit $root and any custom properties 4222 this['$parentContext'] = parentBindingContext; 4223 this['$parent'] = parentBindingContext['$data']; 4224 this['$parents'] = (parentBindingContext['$parents'] || []).slice(0); 4225 this['$parents'].unshift(this['$parent']); 4226 } else { 4227 this['$parents'] = []; 4228 this['$root'] = dataItem; 4229 // Export 'ko' in the binding context so it will be available in bindings and templates 4230 // even if 'ko' isn't exported as a global, such as when using an AMD loader. 4231 // See https://github.com/SteveSanderson/knockout/issues/490 4232 this['ko'] = ko; 4233 } 4234 this['$data'] = dataItem; 4235 if (dataItemAlias) 4236 this[dataItemAlias] = dataItem; 4237 } 4238 ko.bindingContext.prototype['createChildContext'] = function (dataItem, dataItemAlias) { 4239 return new ko.bindingContext(dataItem, this, dataItemAlias); 4240 }; 4241 ko.bindingContext.prototype['extend'] = function(properties) { 4242 var clone = ko.utils.extend(new ko.bindingContext(), this); 4243 return ko.utils.extend(clone, properties); 4244 }; 4245 4246 function validateThatBindingIsAllowedForVirtualElements(bindingName) { 4247 var validator = ko.virtualElements.allowedBindings[bindingName]; 4248 if (!validator) 4249 throw new Error("The binding '" + bindingName + "' cannot be used with virtual elements") 4250 } 4251 4252 function applyBindingsToDescendantsInternal (viewModel, elementOrVirtualElement, bindingContextsMayDifferFromDomParentElement) { 4253 var currentChild, nextInQueue = ko.virtualElements.firstChild(elementOrVirtualElement); 4254 while (currentChild = nextInQueue) { 4255 // Keep a record of the next child *before* applying bindings, in case the binding removes the current child from its position 4256 nextInQueue = ko.virtualElements.nextSibling(currentChild); 4257 applyBindingsToNodeAndDescendantsInternal(viewModel, currentChild, bindingContextsMayDifferFromDomParentElement); 4258 } 4259 } 4260 4261 function applyBindingsToNodeAndDescendantsInternal (viewModel, nodeVerified, bindingContextMayDifferFromDomParentElement) { 4262 var shouldBindDescendants = true; 4263 4264 // Perf optimisation: Apply bindings only if... 4265 // (1) We need to store the binding context on this node (because it may differ from the DOM parent node's binding context) 4266 // Note that we can't store binding contexts on non-elements (e.g., text nodes), as IE doesn't allow expando properties for those 4267 // (2) It might have bindings (e.g., it has a data-bind attribute, or it's a marker for a containerless template) 4268 var isElement = (nodeVerified.nodeType === 1); 4269 if (isElement) // Workaround IE <= 8 HTML parsing weirdness 4270 ko.virtualElements.normaliseVirtualElementDomStructure(nodeVerified); 4271 4272 var shouldApplyBindings = (isElement && bindingContextMayDifferFromDomParentElement) // Case (1)
4273 || ko.bindingProvider['instance']['nodeHasBindings'](nodeVerified); // Case (2) 4274 if (shouldApplyBindings) 4275 shouldBindDescendants = applyBindingsToNodeInternal(nodeVerified, null, viewModel, bindingContextMayDifferFromDomParentElement).shouldBindDescendants; 4276 4277 if (shouldBindDescendants) { 4278 // We're recursing automatically into (real or virtual) child nodes without changing binding contexts. So, 4279 // * For children of a *real* element, the binding context is certainly the same as on their DOM .parentNode, 4280 // hence bindingContextsMayDifferFromDomParentElement is false 4281 // * For children of a *virtual* element, we can't be sure. Evaluating .parentNode on those children may 4282 // skip over any number of intermediate virtual elements, any of which might define a custom binding context, 4283 // hence bindingContextsMayDifferFromDomParentElement is true 4284 applyBindingsToDescendantsInternal(viewModel, nodeVerified, /* bindingContextsMayDifferFromDomParentElement: */ !isElement); 4285 } 4286 } 4287 4288 var boundElementDomDataKey = '__ko_boundElement'; 4289 function applyBindingsToNodeInternal (node, bindings, viewModelOrBindingContext, bindingContextMayDifferFromDomParentElement) { 4290 // Need to be sure that inits are only run once, and updates never run until all the inits have been run 4291 var initPhase = 0; // 0 = before all inits, 1 = during inits, 2 = after all inits 4292 4293 // Each time the dependentObservable is evaluated (after data changes), 4294 // the binding attribute is reparsed so that it can pick out the correct 4295 // model properties in the context of the changed data. 4296 // DOM event callbacks need to be able to access this changed data, 4297 // so we need a single parsedBindings variable (shared by all callbacks 4298 // associated with this node's bindings) that all the closures can access. 4299 var parsedBindings; 4300 function makeValueAccessor(bindingKey) { 4301 return function () { return parsedBindings[bindingKey] } 4302 } 4303 function parsedBindingsAccessor() { 4304 return parsedBindings; 4305 } 4306 4307 var bindingHandlerThatControlsDescendantBindings; 4308 4309 // Prevent multiple applyBindings calls for the same node, except when a binding value is specified 4310 var alreadyBound = ko.utils.domData.get(node, boundElementDomDataKey); 4311 if (!bindings) { 4312 if (alreadyBound) { 4313 throw Error("You cannot apply bindings multiple times to the same element."); 4314 } 4315 ko.utils.domData.set(node, boundElementDomDataKey, true); 4316 } 4317 4318 ko.dependentObservable( 4319 function () { 4320 // Ensure we have a nonnull binding context to work with 4321 var bindingContextInstance = viewModelOrBindingContext && (viewModelOrBindingContext instanceof ko.bindingContext) 4322 ? viewModelOrBindingContext 4323 : new ko.bindingContext(ko.utils.unwrapObservable(viewModelOrBindingContext)); 4324 var viewModel = bindingContextInstance['$data']; 4325 4326 // Optimization: Don't store the binding context on this node if it's definitely the same as on node.parentNode, because 4327 // we can easily recover it just by scanning up the node's ancestors in the DOM 4328 // (note: here, parent node means "real DOM parent" not "virtual parent", as there's no O(1) way to find the virtual parent) 4329 if (!alreadyBound && bindingContextMayDifferFromDomParentElement) 4330 ko.storedBindingContextForNode(node, bindingContextInstance); 4331 4332 // Use evaluatedBindings if given, otherwise fall back on asking the bindings provider to give us some bindings 4333 var evaluatedBindings = (typeof bindings == "function") ? bindings(bindingContextInstance, node) : bindings; 4334 parsedBindings = evaluatedBindings || ko.bindingProvider['
4334instance']['getBindings'](node, bindingContextInstance); 4335 4336 if (parsedBindings) { 4337 // First run all the inits, so bindings can register for notification on changes 4338 if (initPhase === 0) { 4339 initPhase = 1; 4340 ko.utils.objectForEach(parsedBindings, function(bindingKey) { 4341 var binding = ko.bindingHandlers[bindingKey]; 4342 if (binding && node.nodeType === 8) 4343 validateThatBindingIsAllowedForVirtualElements(bindingKey); 4344 4345 if (binding && typeof binding["init"] == "function") { 4346 var handlerInitFn = binding["init"]; 4347 var initResult = handlerInitFn(node, makeValueAccessor(bindingKey), parsedBindingsAccessor, viewModel, bindingContextInstance); 4348 4349 // If this binding handler claims to control descendant bindings, make a note of this 4350 if (initResult && initResult['controlsDescendantBindings']) { 4351 if (bindingHandlerThatControlsDescendantBindings !== undefined) 4352 throw new Error("Multiple bindings (" + bindingHandlerThatControlsDescendantBindings + " and " + bindingKey + ") are trying to control descendant bindings of the same element. You cannot use these bindings together on the same element."); 4353 bindingHandlerThatControlsDescendantBindings = bindingKey; 4354 } 4355 } 4356 }); 4357 initPhase = 2; 4358 } 4359 4360 // ... then run all the updates, which might trigger changes even on the first evaluation 4361 if (initPhase === 2) { 4362 ko.utils.objectForEach(parsedBindings, function(bindingKey) { 4363 var binding = ko.bindingHandlers[bindingKey]; 4364 if (binding && typeof binding["update"] == "function") { 4365 var handlerUpdateFn = binding["update"]; 4366 handlerUpdateFn(node, makeValueAccessor(bindingKey), parsedBindingsAccessor, viewModel, bindingContextInstance); 4367 } 4368 }); 4369 } 4370 } 4371 }, 4372 null, 4373 { disposeWhenNodeIsRemoved : node } 4374 ); 4375 4376 return { 4377 shouldBindDescendants: bindingHandlerThatControlsDescendantBindings === undefined 4378 }; 4379 }; 4380 4381 var storedBindingContextDomDataKey = "__ko_bindingContext__"; 4382 ko.storedBindingContextForNode = function (node, bindingContext) { 4383 if (arguments.length == 2) 4384 ko.utils.domData.set(node, storedBindingContextDomDataKey, bindingContext); 4385 else 4386 return ko.utils.domData.get(node, storedBindingContextDomDataKey); 4387 } 4388 4389 ko.applyBindingsToNode = function (node, bindings, viewModel) { 4390 if (node.nodeType === 1) // If it's an element, workaround IE <= 8 HTML parsing weirdness 4391 ko.virtualElements.normaliseVirtualElementDomStructure(node); 4392 return applyBindingsToNodeInternal(node, bindings, viewModel, true); 4393 }; 4394 4395 ko.applyBindingsToDescendants = function(viewModel, rootNode) { 4396 if (rootNode.nodeType === 1 || rootNode.nodeType === 8) 4397 applyBindingsToDescendantsInternal(viewModel, rootNode, true); 4398 }; 4399 4400 ko.applyBindings = function (viewModel, rootNode) { 4401 if (rootNode && (rootNode.nodeType !== 1) && (rootNode.nodeType !== 8)) 4402 throw new Error("ko.applyBindings: first parameter should be your view model; second parameter should be a DOM node"); 4403 rootNode = rootNode || window.document.body; // Make "rootNode" parameter optional 4404 4405 applyBindingsToNodeAndDescendantsInternal(viewModel, rootNode, true); 4406 }; 4407
4408 // Retrieving binding context from arbitrary nodes 4409 ko.contextFor = function(node) { 4410 // We can only do something meaningful for elements and comment nodes (in particular, not text nodes, as IE can't store domdata for them) 4411 switch (node.nodeType) { 4412 case 1: 4413 case 8: 4414 var context = ko.storedBindingContextForNode(node); 4415 if (context) return context; 4416 if (node.parentNode) return ko.contextFor(node.parentNode); 4417 break; 4418 } 4419 return undefined; 4420 }; 4421 ko.dataFor = function(node) { 4422 var context = ko.contextFor(node); 4423 return context ? context['$data'] : undefined; 4424 }; 4425 4426 ko.exportSymbol('bindingHandlers', ko.bindingHandlers); 4427 ko.exportSymbol('applyBindings', ko.applyBindings); 4428 ko.exportSymbol('applyBindingsToDescendants', ko.applyBindingsToDescendants); 4429 ko.exportSymbol('applyBindingsToNode', ko.applyBindingsToNode); 4430 ko.exportSymbol('contextFor', ko.contextFor); 4431 ko.exportSymbol('dataFor', ko.dataFor); 4432})(); 4433var attrHtmlToJavascriptMap = { 'class': 'className', 'for': 'htmlFor' }; 4434ko.bindingHandlers['attr'] = { 4435 'update': function(element, valueAccessor, allBindingsAccessor) { 4436 var value = ko.utils.unwrapObservable(valueAccessor()) || {}; 4437 ko.utils.objectForEach(value, function(attrName, attrValue) { 4438 attrValue = ko.utils.unwrapObservable(attrValue); 4439 4440 // To cover cases like "attr: { checked:someProp }", we want to remove the attribute entirely 4441 // when someProp is a "no value"-like value (strictly null, false, or undefined) 4442 // (because the absence of the "checked" attr is how to mark an element as not checked, etc.) 4443 var toRemove = (attrValue === false) || (attrValue === null) || (attrValue === undefined); 4444 if (toRemove) 4445 element.removeAttribute(attrName); 4446 4447 // In IE <= 7 and IE8 Quirks Mode, you have to use the Javascript property name instead of the 4448 // HTML attribute name for certain attributes. IE8 Standards Mode supports the correct behavior, 4449 // but instead of figuring out the mode, we'll just set the attribute through the Javascript 4450 // property for IE <= 8. 4451 if (ko.utils.ieVersion <= 8 && attrName in attrHtmlToJavascriptMap) { 4452 attrName = attrHtmlToJavascriptMap[attrName]; 4453 if (toRemove) 4454 element.removeAttribute(attrName); 4455 else 4456 element[attrName] = attrValue; 4457 } else if (!toRemove) { 4458 element.setAttribute(attrName, attrValue.toString()); 4459 } 4460 4461 // Treat "name" specially - although you can think of it as an attribute, it also needs 4462 // special handling on older versions of IE (https://github.com/SteveSanderson/knockout/pull/333) 4463 // Deliberately being case-sensitive here because XHTML would regard "Name" as a different thing 4464 // entirely, and there's no strong reason to allow for such casing in HTML. 4465 if (attrName === "name") { 4466 ko.utils.setElementName(element, toRemove ? "" : attrValue.toString()); 4467 } 4468 }); 4469 } 4470}; 4471ko.bindingHandlers['checked'] = { 4472 'init': function (element, valueAccessor, allBindingsAccessor) { 4473 var updateHandler = function() { 4474 var valueToWrite; 4475 if (element.type == "checkbox") { 4476 valueToWrite = element.checked; 4477 } else if ((element.type == "radio") && (element.checked)) { 4478 valueToWrite = element.value; 4479 } else { 4480 return; // "checked" binding only responds to checkboxes and selected radio buttons 4481 } 4482 4483 var modelValue = valueAccessor(), unwrappedValue = ko.utils.unwrapObservable(modelValue); 4484 if ((element.type == "checkbox") && (unwrappedValue instanceof Array)) { 4485 // For checkboxes bound to an array, we add/remove the checkbox value to that array 4486 // This works for both observable and non-observable arrays 4487 ko.utils.addOrRemoveItem(modelValue, element.value, element.checked); 4488 } else { 4489 ko.expressionRewriting.writeValueToProperty(modelValue, allBindingsAccessor, 'checked', valueToWrite, true); 4490 } 4491 }; 4492 ko.utils.registerEventHandler(element, "click", updateHandler); 4493 4494 // IE 6 won't allow radio buttons to be selected unless they have a name 4495 if ((element.type == "radio") && !element.name) 4496 ko.bindingHandlers['uniqueName']['init'](element, function() { return true });
4497 }, 4498 'update': function (element, valueAccessor) { 4499 var value = ko.utils.unwrapObservable(valueAccessor()); 4500 4501 if (element.type == "checkbox") { 4502 if (value instanceof Array) { 4503 // When bound to an array, the checkbox being checked represents its value being present in that array 4504 element.checked = ko.utils.arrayIndexOf(value, element.value) >= 0; 4505 } else { 4506 // When bound to any other value (not an array), the checkbox being checked represents the value being trueish 4507 element.checked = value; 4508 } 4509 } else if (element.type == "radio") { 4510 element.checked = (element.value == value); 4511 } 4512 } 4513}; 4514var classesWrittenByBindingKey = '__ko__cssValue'; 4515ko.bindingHandlers['css'] = { 4516 'update': function (element, valueAccessor) { 4517 var value = ko.utils.unwrapObservable(valueAccessor()); 4518 if (typeof value == "object") { 4519 ko.utils.objectForEach(value, function(className, shouldHaveClass) { 4520 shouldHaveClass = ko.utils.unwrapObservable(shouldHaveClass); 4521 ko.utils.toggleDomNodeCssClass(element, className, shouldHaveClass); 4522 }); 4523 } else { 4524 value = String(value || ''); // Make sure we don't try to store or set a non-string value 4525 ko.utils.toggleDomNodeCssClass(element, element[classesWrittenByBindingKey], false); 4526 element[classesWrittenByBindingKey] = value; 4527 ko.utils.toggleDomNodeCssClass(element, value, true); 4528 } 4529 } 4530}; 4531ko.bindingHandlers['enable'] = { 4532 'update': function (element, valueAccessor) { 4533 var value = ko.utils.unwrapObservable(valueAccessor()); 4534 if (value && element.disabled) 4535 element.removeAttribute("disabled"); 4536 else if ((!value) && (!element.disabled)) 4537 element.disabled = true; 4538 } 4539}; 4540 4541ko.bindingHandlers['disable'] = { 4542 'update': function (element, valueAccessor) { 4543 ko.bindingHandlers['enable']['update'](element, function() { return !ko.utils.unwrapObservable(valueAccessor()) }); 4544 } 4545}; 4546// For certain common events (currently just 'click'), allow a simplified data-binding syntax 4547// e.g. click:handler instead of the usual full-length event:{click:handler} 4548function makeEventHandlerShortcut(eventName) { 4549 ko.bindingHandlers[eventName] = { 4550 'init': function(element, valueAccessor, allBindingsAccessor, viewModel) { 4551 var newValueAccessor = function () { 4552 var result = {}; 4553 result[eventName] = valueAccessor(); 4554 return result; 4555 }; 4556 return ko.bindingHandlers['event']['init'].call(this, element, newValueAccessor, allBindingsAccessor, viewModel); 4557 } 4558 } 4559} 4560 4561ko.bindingHandlers['event'] = { 4562 'init' : function (element, valueAccessor, allBindingsAccessor, viewModel) { 4563 var eventsToHandle = valueAccessor() || {}; 4564 ko.utils.objectForEach(eventsToHandle, function(eventName) { 4565 if (typeof eventName == "string") { 4566 ko.utils.registerEventHandler(element, eventName, function (event) { 4567 var handlerReturnValue; 4568 var handlerFunction = valueAccessor()[eventName]; 4569 if (!handlerFunction) 4570 return; 4571 var allBindings = allBindingsAccessor(); 4572 4573 try { 4574 // Take all the event args, and prefix with the viewmodel 4575 var argsForHandler = ko.utils.makeArray(arguments); 4576 argsForHandler.unshift(viewModel); 4577 handlerReturnValue = handlerFunction.apply(viewModel, argsForHandler); 4578 } finally { 4579 if (handlerReturnValue !== true) { // Normally we want to prevent default action. Developer can override this be explicitly returning true. 4580 if (event.preventDefault) 4581 event.preventDefault(); 4582 else 4583 event.returnValue = false; 4584 } 4585 } 4586 4587 var bubble = allBindings[eventName + 'Bubble'] !== false; 4588 if (!bubble) { 4589 event.cancelBubble = true; 4590 if (event.stopPropagation) 4591 event.stopPropagation(); 4592 } 4593 }); 4594 } 4595 }); 4596 } 4597}; 4598// "foreach: someExpression" is equivalent to "template: { foreach: someExpression }" 4599// "foreach: { data: someExpression, afterAdd: myfn }" is equivalent to "template: { foreach: someExpression, afterAdd: myfn }" 4600ko.bindingHandlers['foreach'] = { 4601 makeTemplateValueAccessor: function(valueAccessor) { 4602 return function() { 4603 var modelValue = valueAccessor(), 4604 unwrappedValue = ko.utils.peekObservable(modelValue); // Unwrap without setting a dependency here 4605 4606 // If unwrappedValue is the array, pass in the wrapped value on its own 4607 // The value will be unwrapped and tracked within the template binding 4608 // (See https://github.com/SteveSanderson/knockout/issues/523) 4609 if ((!unwrappedValue) || typeof unwrappedValue.length == "number") 4610 return { 'foreach': modelValue, 'templateEngine': ko.nativeTemplateEngine.instance }; 4611 4612 // If unwrappedValue.data is the array, preserve all relevant options and unwrap again value so we get updates 4613 ko.utils.unwrapObservable(modelValue); 4614 return { 4615 'foreach': unwrappedValue['data'], 4616 'as': unwrappedValue['as'], 4617 'includeDestroyed': unwrappedValue['includeDestroyed'], 4618 'afterAdd': unwrappedValue['afterAdd'], 4619 'beforeRemove': unwrappedValue['beforeRemove'],
vendor: 5,724 bytes, lines 4620-4716
4620 'afterRender': unwrappedValue['afterRender'], 4621 'beforeMove': unwrappedValue['beforeMove'], 4622 'afterMove': unwrappedValue['afterMove'], 4623 'templateEngine': ko.nativeTemplateEngine.instance 4624 }; 4625 }; 4626 }, 4627 'init': function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 4628 return ko.bindingHandlers['template']['init'](element, ko.bindingHandlers['foreach'].makeTemplateValueAccessor(valueAccessor)); 4629 }, 4630 'update': function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 4631 return ko.bindingHandlers['template']['update'](element, ko.bindingHandlers['foreach'].makeTemplateValueAccessor(valueAccessor), allBindingsAccessor, viewModel, bindingContext); 4632 } 4633}; 4634ko.expressionRewriting.bindingRewriteValidators['foreach'] = false; // Can't rewrite control flow bindings 4635ko.virtualElements.allowedBindings['foreach'] = true; 4636var hasfocusUpdatingProperty = '__ko_hasfocusUpdating'; 4637var hasfocusLastValue = '__ko_hasfocusLastValue'; 4638ko.bindingHandlers['hasfocus'] = { 4639 'init': function(element, valueAccessor, allBindingsAccessor) { 4640 var handleElementFocusChange = function(isFocused) { 4641 // Where possible, ignore which event was raised and determine focus state using activeElement, 4642 // as this avoids phantom focus/blur events raised when changing tabs in modern browsers. 4643 // However, not all KO-targeted browsers (Firefox 2) support activeElement. For those browsers, 4644 // prevent a loss of focus when changing tabs/windows by setting a flag that prevents hasfocus 4645 // from calling 'blur()' on the element when it loses focus. 4646 // Discussion at https://github.com/SteveSanderson/knockout/pull/352 4647 element[hasfocusUpdatingProperty] = true; 4648 var ownerDoc = element.ownerDocument; 4649 if ("activeElement" in ownerDoc) { 4650 var active; 4651 try { 4652 active = ownerDoc.activeElement; 4653 } catch(e) { 4654 // IE9 throws if you access activeElement during page load (see issue #703) 4655 active = ownerDoc.body; 4656 } 4657 isFocused = (active === element); 4658 } 4659 var modelValue = valueAccessor(); 4660 ko.expressionRewriting.writeValueToProperty(modelValue, allBindingsAccessor, 'hasfocus', isFocused, true); 4661 4662 //cache the latest value, so we can avoid unnecessarily calling focus/blur in the update function 4663 element[hasfocusLastValue] = isFocused; 4664 element[hasfocusUpdatingProperty] = false; 4665 }; 4666 var handleElementFocusIn = handleElementFocusChange.bind(null, true); 4667 var handleElementFocusOut = handleElementFocusChange.bind(null, false); 4668 4669 ko.utils.registerEventHandler(element, "focus", handleElementFocusIn); 4670 ko.utils.registerEventHandler(element, "focusin", handleElementFocusIn); // For IE 4671 ko.utils.registerEventHandler(element, "blur", handleElementFocusOut); 4672 ko.utils.registerEventHandler(element, "focusout", handleElementFocusOut); // For IE 4673 }, 4674 'update': function(element, valueAccessor) { 4675 var value = !!ko.utils.unwrapObservable(valueAccessor()); //force boolean to compare with last value 4676 if (!element[hasfocusUpdatingProperty] && element[hasfocusLastValue] !== value) { 4677 value ? element.focus() : element.blur(); 4678 ko.dependencyDetection.ignore(ko.utils.triggerEvent, null, [element, value ? "focusin" : "focusout"]); // For IE, which doesn't reliably fire "focus" or "blur" events synchronously 4679 } 4680 } 4681}; 4682 4683ko.bindingHandlers['hasFocus'] = ko.bindingHandlers['hasfocus']; // Make "hasFocus" an alias 4684ko.bindingHandlers['html'] = { 4685 'init': function() { 4686 // Prevent binding on the dynamically-injected HTML (as developers are unlikely to expect that, and it has security implications) 4687 return { 'controlsDescendantBindings': true }; 4688 }, 4689 'update': function (element, valueAccessor) { 4690 // setHtml will unwrap the value if needed 4691 ko.utils.setHtml(element, valueAccessor()); 4692 } 4693}; 4694var withIfDomDataKey = '__ko_withIfBindingData'; 4695// Makes a binding like with or if 4696function makeWithIfBinding(bindingKey, isWith, isNot, makeContextCallback) { 4697 ko.bindingHandlers[bindingKey] = { 4698 'init': function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 4699 ko.utils.domData.set(element, withIfDomDataKey, {}); 4700 return { 'controlsDescendantBindings': true }; 4701 }, 4702 'update': function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 4703 var withIfData = ko.utils.domData.get(element, withIfDomDataKey), 4704 dataValue = ko.utils.unwrapObservable(valueAccessor()), 4705 shouldDisplay = !isNot !== !dataValue, // equivalent to isNot ? !dataValue : !!dataValue 4706 isFirstRender = !withIfData.savedNodes, 4707 needsRefresh = isFirstRender || isWith || (shouldDisplay !== withIfData.didDisplayOnLastUpdate); 4708 4709 if (needsRefresh) { 4710 if (isFirstRender) { 4711 withIfData.savedNodes = ko.utils.cloneNodes(ko.virtualElements.childNodes(element), true /* shouldCleanNodes */); 4712 } 4713 4714 if (shouldDisplay) { 4715 if (!isFirstRender) { 4716 ko.virtualElements.setDomNodeChildren(element, ko.utils.cloneNodes(withIfData.savedNodes
4716)); 4717 } 4718 ko.applyBindingsToDescendants(makeContextCallback ? makeContextCallback(bindingContext, dataValue) : bindingContext, element); 4719 } else { 4720 ko.virtualElements.emptyNode(element); 4721 } 4722 4723 withIfData.didDisplayOnLastUpdate = shouldDisplay; 4724 } 4725 } 4726 }; 4727 ko.expressionRewriting.bindingRewriteValidators[bindingKey] = false; // Can't rewrite control flow bindings 4728 ko.virtualElements.allowedBindings[bindingKey] = true; 4729} 4730 4731// Construct the actual binding handlers 4732makeWithIfBinding('if'); 4733makeWithIfBinding('ifnot', false /* isWith */, true /* isNot */); 4734makeWithIfBinding('with', true /* isWith */, false /* isNot */, 4735 function(bindingContext, dataValue) { 4736 return bindingContext['createChildContext'](dataValue); 4737 } 4738); 4739function ensureDropdownSelectionIsConsistentWithModelValue(element, modelValue, preferModelValue) { 4740 if (preferModelValue) { 4741 if (modelValue !== ko.selectExtensions.readValue(element)) 4742 ko.selectExtensions.writeValue(element, modelValue); 4743 } 4744 4745 // No matter which direction we're syncing in, we want the end result to be equality between dropdown value and model value. 4746 // If they aren't equal, either we prefer the dropdown value, or the model value couldn't be represented, so either way, 4747 // change the model value to match the dropdown. 4748 if (modelValue !== ko.selectExtensions.readValue(element)) 4749 ko.dependencyDetection.ignore(ko.utils.triggerEvent, null, [element, "change"]); 4750}; 4751 4752ko.bindingHandlers['options'] = { 4753 'init': function(element) { 4754 if (ko.utils.tagNameLower(element) !== "select") 4755 throw new Error("options binding applies only to SELECT elements"); 4756 4757 // Remove all existing <option>s. 4758 while (element.length > 0) { 4759 element.remove(0); 4760 } 4761 4762 // Ensures that the binding processor doesn't try to bind the options 4763 return { 'controlsDescendantBindings': true }; 4764 }, 4765 'update': function (element, valueAccessor, allBindingsAccessor) { 4766 var selectWasPreviouslyEmpty = element.length == 0; 4767 var previousScrollTop = (!selectWasPreviouslyEmpty && element.multiple) ? element.scrollTop : null; 4768 4769 var unwrappedArray = ko.utils.unwrapObservable(valueAccessor()); 4770 var allBindings = allBindingsAccessor(); 4771 var includeDestroyed = allBindings['optionsIncludeDestroyed']; 4772 var captionPlaceholder = {}; 4773 var captionValue; 4774 var previousSelectedValues; 4775 if (element.multiple) { 4776 previousSelectedValues = ko.utils.arrayMap(element.selectedOptions || ko.utils.arrayFilter(element.childNodes, function (node) { 4777 return node.tagName && (ko.utils.tagNameLower(node) === "option") && node.selected; 4778 }), function (node) { 4779 return ko.selectExtensions.readValue(node); 4780 }); 4781 } else if (element.selectedIndex >= 0) { 4782 previousSelectedValues = [ ko.selectExtensions.readValue(element.options[element.selectedIndex]) ]; 4783 } 4784 4785 if (unwrappedArray) { 4786 if (typeof unwrappedArray.length == "undefined") // Coerce single value into array 4787 unwrappedArray = [unwrappedArray]; 4788 4789 // Filter out any entries marked as destroyed 4790 var filteredArray = ko.utils.arrayFilter(unwrappedArray, function(item) { 4791 return includeDestroyed || item === undefined || item === null || !ko.utils.unwrapObservable(item['_destroy']); 4792 }); 4793 4794 // If caption is included, add it to the array 4795 if ('optionsCaption' in allBindings) { 4796 captionValue = ko.utils.unwrapObservable(allBindings['optionsCaption']); 4797 // If caption value is null or undefined, don't show a caption 4798 if (captionValue !== null && captionValue !== undefined) { 4799 filteredArray.unshift(captionPlaceholder); 4800 } 4801 } 4802 } else { 4803 // If a falsy value is provided (e.g. null), we'll simply empty the select element 4804 unwrappedArray = []; 4805 } 4806 4807 function applyToObject(object, predicate, defaultValue) { 4808 var predicateType = typeof predicate; 4809 if (predicateType == "function") // Given a function; run it against the data value 4810 return predicate(object); 4811 else if (predicateType == "string") // Given a string; treat it as a property name on the data value 4812 return object[predicate]; 4813 else // Given no optionsText arg; use the data value itself 4814 return defaultValue; 4815 } 4816 4817 // The following functions can run at two different times:
4818 // The first is when the whole array is being updated directly from this binding handler. 4819 // The second is when an observable value for a specific array entry is updated. 4820 // oldOptions will be empty in the first case, but will be filled with the previously generated option in the second. 4821 function optionForArrayItem(arrayEntry, index, oldOptions) { 4822 if (oldOptions.length) { 4823 previousSelectedValues = oldOptions[0].selected && [ ko.selectExtensions.readValue(oldOptions[0]) ]; 4824 } 4825 var option = document.createElement("option"); 4826 if (arrayEntry === captionPlaceholder) { 4827 ko.utils.setHtml(option, captionValue); 4828 ko.selectExtensions.writeValue(option, undefined); 4829 } else { 4830 // Apply a value to the option element 4831 var optionValue = applyToObject(arrayEntry, allBindings['optionsValue'], arrayEntry); 4832 ko.selectExtensions.writeValue(option, ko.utils.unwrapObservable(optionValue)); 4833 4834 // Apply some text to the option element 4835 var optionText = applyToObject(arrayEntry, allBindings['optionsText'], optionValue); 4836 ko.utils.setTextContent(option, optionText); 4837 } 4838 return [option]; 4839 } 4840 4841 function setSelectionCallback(arrayEntry, newOptions) { 4842 // IE6 doesn't like us to assign selection to OPTION nodes before they're added to the document. 4843 // That's why we first added them without selection. Now it's time to set the selection. 4844 if (previousSelectedValues) { 4845 var isSelected = ko.utils.arrayIndexOf(previousSelectedValues, ko.selectExtensions.readValue(newOptions[0])) >= 0; 4846 ko.utils.setOptionNodeSelectionState(newOptions[0], isSelected); 4847 } 4848 } 4849 4850 var callback = setSelectionCallback; 4851 if (allBindings['optionsAfterRender']) { 4852 callback = function(arrayEntry, newOptions) { 4853 setSelectionCallback(arrayEntry, newOptions); 4854 ko.dependencyDetection.ignore(allBindings['optionsAfterRender'], null, [newOptions[0], arrayEntry !== captionPlaceholder ? arrayEntry : undefined]); 4855 } 4856 } 4857 4858 ko.utils.setDomNodeChildrenFromArrayMapping(element, filteredArray, optionForArrayItem, null, callback); 4859 4860 // Clear previousSelectedValues so that future updates to individual objects don't get stale data 4861 previousSelectedValues = null; 4862 4863 if (selectWasPreviouslyEmpty && ('value' in allBindings)) { 4864 // Ensure consistency between model value and selected option. 4865 // If the dropdown is being populated for the first time here (or was otherwise previously empty), 4866 // the dropdown selection state is meaningless, so we preserve the model value. 4867 ensureDropdownSelectionIsConsistentWithModelValue(element, ko.utils.peekObservable(allBindings['value']), /* preferModelValue */ true); 4868 } 4869 4870 // Workaround for IE bug 4871 ko.utils.ensureSelectElementIsRenderedCorrectly(element); 4872 4873 if (previousScrollTop && Math.abs(previousScrollTop - element.scrollTop) > 20) 4874 element.scrollTop = previousScrollTop; 4875 } 4876}; 4877ko.bindingHandlers['options'].optionValueDomDataKey = '__ko.optionValueDomData__'; 4878ko.bindingHandlers['selectedOptions'] = { 4879 'init': function (element, valueAccessor, allBindingsAccessor) { 4880 ko.utils.registerEventHandler(element, "change", function () { 4881 var value = valueAccessor(), valueToWrite = []; 4882 ko.utils.arrayForEach(element.getElementsByTagName("option"), function(node) { 4883 if (node.selected) 4884 valueToWrite.push(ko.selectExtensions.readValue(node)); 4885 }); 4886 ko.expressionRewriting.writeValueToProperty(value, allBindingsAccessor, 'selectedOptions', valueToWrite); 4887 }); 4888 }, 4889 'update': function (element, valueAccessor) { 4890 if (ko.utils.tagNameLower(element) != "select") 4891 throw new Error("values binding applies only to SELECT elements"); 4892 4893 var newValue = ko.utils.unwrapObservable(valueAccessor()); 4894 if (newValue && typeof newValue.length == "number") { 4895 ko.utils.arrayForEach(element.getElementsByTagName("option"), function(node) { 4896 var isSelected = ko.utils.arrayIndexOf(newValue, ko.selectExtensions.readValue(node)) >= 0; 4897 ko.utils.setOptionNodeSelectionState(node, isSelected); 4898 }); 4899 } 4900 } 4901}; 4902ko.bindingHandlers['style'] = { 4903 'update': function (element, valueAccessor) { 4904 var value = ko.utils.unwrapObservable(valueAccessor() || {}); 4905 ko.utils.objectForEach(value, function(styleName, styleValue) { 4906 styleValue = ko.utils.unwrapObservable(styleValue); 4907 element.style[styleName] = styleValue || ""; // Empty string removes the value, whereas null/undefined have no effect 4908 }); 4909 } 4910}; 4911ko.bindingHandlers['submit'] = { 4912 'init': function (element, valueAccessor, allBindingsAccessor, viewModel) { 4913 if (typeof valueAccessor() != "function") 4914 throw new Error("The value for a submit binding must be a function"); 4915 ko.utils.registerEventHandler(element, "submit", function (event) { 4916 var handlerReturnValue; 4917 var value = valueAccessor(); 4918 try { handlerReturnValue = value.call(viewModel, element); } 4919 finally { 4920 if (handlerReturnValue !== true) { // Normally we want to prevent default action. Developer can override this be explicitly returning true. 4921 if (event.preventDefault) 4922 event.preventDefault(); 4923 else 4924 event.returnValue = false; 4925 } 4926 } 4927 }); 4928 } 4929}; 4930ko.bindingHandlers['text'] = { 4931 'update': function (element, valueAccessor) { 4932 ko.utils.setTextContent(element, valueAccessor()); 4933 } 4934}; 4935ko.virtualElements.allowedBindings['text'] = true; 4936ko.bindingHandlers['uniqueName'] = { 4937 'init': function (element, valueAccessor) { 4938 if (valueAccessor()) { 4939 var name = "ko_unique_" + (++ko.bindingHandlers['uniqueName'].currentIndex); 4940 ko.utils.setElementName(element, name); 4941 } 4942 } 4943}; 4944ko.bindingHandlers['uniqueName'].currentIndex = 0; 4945ko.bindingHandlers['value'] = { 4946 'init': function (element, valueAccessor, allBindingsAccessor) { 4947 // Always catch "change" event; possibly other events too if asked 4948 var eventsToCatch = ["change"]; 4949 var requestedEventsToCatch = allBindingsAccessor()["valueUpdate"]; 4950 var propertyChangedFired = false; 4951 if (requestedEventsToCatch) { 4952 if (typeof requestedEventsToCatch == "string") // Allow both individual event names, and arrays of event names 4953 requestedEventsToCatch = [requestedEventsToCatch];
4954 ko.utils.arrayPushAll(eventsToCatch, requestedEventsToCatch); 4955 eventsToCatch = ko.utils.arrayGetDistinctValues(eventsToCatch); 4956 } 4957 4958 var valueUpdateHandler = function() { 4959 propertyChangedFired = false; 4960 var modelValue = valueAccessor(); 4961 var elementValue = ko.selectExtensions.readValue(element); 4962 ko.expressionRewriting.writeValueToProperty(modelValue, allBindingsAccessor, 'value', elementValue); 4963 } 4964 4965 // Workaround for https://github.com/SteveSanderson/knockout/issues/122 4966 // IE doesn't fire "change" events on textboxes if the user selects a value from its autocomplete list 4967 var ieAutoCompleteHackNeeded = ko.utils.ieVersion && element.tagName.toLowerCase() == "input" && element.type == "text" 4968 && element.autocomplete != "off" && (!element.form || element.form.autocomplete != "off"); 4969 if (ieAutoCompleteHackNeeded && ko.utils.arrayIndexOf(eventsToCatch, "propertychange") == -1) { 4970 ko.utils.registerEventHandler(element, "propertychange", function () { propertyChangedFired = true }); 4971 ko.utils.registerEventHandler(element, "blur", function() { 4972 if (propertyChangedFired) { 4973 valueUpdateHandler(); 4974 } 4975 }); 4976 } 4977 4978 ko.utils.arrayForEach(eventsToCatch, function(eventName) { 4979 // The syntax "after<eventname>" means "run the handler asynchronously after the event" 4980 // This is useful, for example, to catch "keydown" events after the browser has updated the control 4981 // (otherwise, ko.selectExtensions.readValue(this) will receive the control's value *before* the key event) 4982 var handler = valueUpdateHandler; 4983 if (ko.utils.stringStartsWith(eventName, "after")) { 4984 handler = function() { setTimeout(valueUpdateHandler, 0) }; 4985 eventName = eventName.substring("after".length); 4986 } 4987 ko.utils.registerEventHandler(element, eventName, handler); 4988 }); 4989 }, 4990 'update': function (element, valueAccessor) { 4991 var valueIsSelectOption = ko.utils.tagNameLower(element) === "select"; 4992 var newValue = ko.utils.unwrapObservable(valueAccessor()); 4993 var elementValue = ko.selectExtensions.readValue(element); 4994 var valueHasChanged = (newValue !== elementValue); 4995 4996 if (valueHasChanged) { 4997 var applyValueAction = function () { ko.selectExtensions.writeValue(element, newValue); }; 4998 applyValueAction(); 4999 5000 // Workaround for IE6 bug: It won't reliably apply values to SELECT nodes during the same execution thread 5001 // right after you've changed the set of OPTION nodes on it. So for that node type, we'll schedule a second thread 5002 // to apply the value as well. 5003 var alsoApplyAsynchronously = valueIsSelectOption; 5004 if (alsoApplyAsynchronously) 5005 setTimeout(applyValueAction, 0); 5006 } 5007 5008 // If you try to set a model value that can't be represented in an already-populated dropdown, reject that change, 5009 // because you're not allowed to have a model value that disagrees with a visible UI selection. 5010 if (valueIsSelectOption && (element.length > 0)) 5011 ensureDropdownSelectionIsConsistentWithModelValue(element, newValue, /* preferModelValue */ false); 5012 } 5013}; 5014ko.bindingHandlers['visible'] = { 5015 'update': function (element, valueAccessor) { 5016 var value = ko.utils.unwrapObservable(valueAccessor()); 5017 var isCurrentlyVisible = !(element.style.display == "none"); 5018 if (value && !isCurrentlyVisible) 5019 element.style.display = ""; 5020 else if ((!value) && isCurrentlyVisible) 5021 element.style.display = "none"; 5022 } 5023}; 5024// 'click' is just a shorthand for the usual full-length event:{click:handler} 5025makeEventHandlerShortcut('click'); 5026// If you want to make a custom template engine,
vendor: 8,284 bytes, lines 5027-5172
5027// 5028// [1] Inherit from this class (like ko.nativeTemplateEngine does) 5029// [2] Override 'renderTemplateSource', supplying a function with this signature: 5030// 5031// function (templateSource, bindingContext, options) { 5032// // - templateSource.text() is the text of the template you should render 5033// // - bindingContext.$data is the data you should pass into the template 5034// // - you might also want to make bindingContext.$parent, bindingContext.$parents, 5035// // and bindingContext.$root available in the template too 5036// // - options gives you access to any other properties set on "data-bind: { template: options }" 5037// // 5038// // Return value: an array of DOM nodes 5039// } 5040// 5041// [3] Override 'createJavaScriptEvaluatorBlock', supplying a function with this signature: 5042// 5043// function (script) { 5044// // Return value: Whatever syntax means "Evaluate the JavaScript statement 'script' and output the result" 5045// // For example, the jquery.tmpl template engine converts 'someScript' to '${ someScript }' 5046// } 5047// 5048// This is only necessary if you want to allow data-bind attributes to reference arbitrary template variables. 5049// If you don't want to allow that, you can set the property 'allowTemplateRewriting' to false (like ko.nativeTemplateEngine does) 5050// and then you don't need to override 'createJavaScriptEvaluatorBlock'. 5051 5052ko.templateEngine = function () { }; 5053 5054ko.templateEngine.prototype['renderTemplateSource'] = function (templateSource, bindingContext, options) { 5055 throw new Error("Override renderTemplateSource"); 5056}; 5057 5058ko.templateEngine.prototype['createJavaScriptEvaluatorBlock'] = function (script) { 5059 throw new Error("Override createJavaScriptEvaluatorBlock"); 5060}; 5061 5062ko.templateEngine.prototype['makeTemplateSource'] = function(template, templateDocument) { 5063 // Named template 5064 if (typeof template == "string") { 5065 templateDocument = templateDocument || document; 5066 var elem = templateDocument.getElementById(template); 5067 if (!elem) 5068 throw new Error("Cannot find template with ID " + template); 5069 return new ko.templateSources.domElement(elem); 5070 } else if ((template.nodeType == 1) || (template.nodeType == 8)) { 5071 // Anonymous template 5072 return new ko.templateSources.anonymousTemplate(template); 5073 } else 5074 throw new Error("Unknown template type: " + template); 5075}; 5076 5077ko.templateEngine.prototype['renderTemplate'] = function (template, bindingContext, options, templateDocument) { 5078 var templateSource = this['makeTemplateSource'](template, templateDocument); 5079 return this['renderTemplateSource'](templateSource, bindingContext, options); 5080}; 5081 5082ko.templateEngine.prototype['isTemplateRewritten'] = function (template, templateDocument) { 5083 // Skip rewriting if requested 5084 if (this['allowTemplateRewriting'] === false) 5085 return true; 5086 return this['makeTemplateSource'](template, templateDocument)['data']("isRewritten"); 5087}; 5088 5089ko.templateEngine.prototype['rewriteTemplate'] = function (template, rewriterCallback, templateDocument) { 5090 var templateSource = this['makeTemplateSource'](template, templateDocument); 5091 var rewritten = rewriterCallback(templateSource['text']()); 5092 templateSource['text'](rewritten); 5093 templateSource['data']("isRewritten", true); 5094}; 5095 5096ko.exportSymbol('templateEngine', ko.templateEngine); 5097 5098ko.templateRewriting = (function () { 5099 var memoizeDataBindingAttributeSyntaxRegex = /(<([a-z]+\d*)(?:\s+(?!data-bind\s*=\s*)[a-z0-9\-]+(?:=(?:\"[^\"]*\"|\'[^\']*\'))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi; 5100 var memoizeVirtualContainerBindingSyntaxRegex = /<!--\s*ko\b\s*([\s\S]*?)\s*-->/g; 5101 5102 function validateDataBindValuesForRewriting(keyValueArray) { 5103 var allValidators = ko.expressionRewriting.bindingRewriteValidators; 5104 for (var i = 0; i < keyValueArray.length; i++) { 5105 var key = keyValueArray[i]['key']; 5106 if (allValidators.hasOwnProperty(key)) { 5107 var validator = allValidators[key]; 5108 5109 if (typeof validator === "function") { 5110 var possibleErrorMessage = validator(keyValueArray[i]['value']); 5111 if (possibleErrorMessage) 5112 throw new Error(possibleErrorMessage); 5113 } else if (!validator) { 5114 throw new Error("This template engine does not support the '" + key + "' binding within its templates"); 5115 } 5116 } 5117 } 5118 } 5119 5120 function constructMemoizedTagReplacement(dataBindAttributeValue, tagToRetain, nodeName, templateEngine) { 5121 var dataBindKeyValueArray = ko.expressionRewriting.parseObjectLiteral(dataBindAttributeValue); 5122 validateDataBindValuesForRewriting(dataBindKeyValueArray); 5123 var rewrittenDataBindAttributeValue = ko.expressionRewriting.preProcessBindings(dataBindKeyValueArray); 5124 5125 // For no obvious reason, Opera fails to evaluate rewrittenDataBindAttributeValue unless it's wrapped in an additional 5126 // anonymous function, even though Opera's built-in debugger can evaluate it anyway. No other browser requires this 5127 // extra indirection. 5128 var applyBindingsToNextSiblingScript = 5129 "ko.__tr_ambtns(function($context,$element){return(function(){return{ " + rewrittenDataBindAttributeValue + " } })()},'" + nodeName.toLowerCase() + "')"; 5130 return templateEngine['createJavaScriptEvaluatorBlock'](applyBindingsToNextSiblingScript) + tagToRetain; 5131 } 5132 5133 return { 5134 ensureTemplateIsRewritten: function (template, templateEngine, templateDocument) { 5135 if (!templateEngine['isTemplateRewritten'](template, templateDocument)) 5136 templateEngine['rewriteTemplate'](template, function (htmlString) { 5137 return ko.templateRewriting.memoizeBindingAttributeSyntax(htmlString, templateEngine); 5138 }, templateDocument); 5139 }, 5140 5141 memoizeBindingAttributeSyntax: function (htmlString, templateEngine) { 5142 return htmlString.replace(memoizeDataBindingAttributeSyntaxRegex, function () { 5143 return constructMemoizedTagReplacement(/* dataBindAttributeValue: */ arguments[4], /* tagToRetain: */ arguments[1], /* nodeName: */ arguments[2], templateEngine); 5144 }).replace(memoizeVirtualContainerBindingSyntaxRegex, function() { 5145 return constructMemoizedTagReplacement(/* dataBindAttributeValue: */ arguments[1], /* tagToRetain: */ "<!-- ko -->", /* nodeName: */ "#comment", templateEngine); 5146 }); 5147 }, 5148 5149 applyMemoizedBindingsToNextSibling: function (bindings, nodeName) { 5150 return ko.memoization.memoize(function (domNode, bindingContext) { 5151 var nodeToBind = domNode.nextSibling; 5152 if (nodeToBind && nodeToBind.nodeName.toLowerCase() === nodeName) { 5153 ko.applyBindingsToNode(nodeToBind, bindings, bindingContext); 5154 } 5155 }); 5156 } 5157 } 5158})(); 5159 5160 5161// Exported only because it has to be referenced by string lookup from within rewritten template 5162ko.exportSymbol('__tr_ambtns', ko.templateRewriting.applyMemoizedBindingsToNextSibling); 5163(function() { 5164 // A template source represents a read/write way of accessing a template. This is to eliminate the need for template loading/saving 5165 // logic to be duplicated in every template engine (and means they can all work with anonymous templates, etc.) 5166 // 5167 // Two are provided by default: 5168 // 1. ko.templateSources.domElement - reads/writes the text content of an arbitrary DOM element 5169 // 2. ko.templateSources.anonymousElement - uses ko.utils.domData to read/write text *associated* with the DOM element, but 5170 // without reading/writing the actual element text content, since it will be overwritten 5171 // with the rendered template output. 5172 // You can implement your own template source if you want to fetch/store templates somewhere other than
5172in DOM elements. 5173 // Template sources need to have the following functions: 5174 // text() - returns the template text from your storage location 5175 // text(value) - writes the supplied template text to your storage location 5176 // data(key) - reads values stored using data(key, value) - see below 5177 // data(key, value) - associates "value" with this template and the key "key". Is used to store information like "isRewritten". 5178 // 5179 // Optionally, template sources can also have the following functions: 5180 // nodes() - returns a DOM element containing the nodes of this template, where available 5181 // nodes(value) - writes the given DOM element to your storage location 5182 // If a DOM element is available for a given template source, template engines are encouraged to use it in preference over text() 5183 // for improved speed. However, all templateSources must supply text() even if they don't supply nodes(). 5184 // 5185 // Once you've implemented a templateSource, make your template engine use it by subclassing whatever template engine you were 5186 // using and overriding "makeTemplateSource" to return an instance of your custom template source. 5187 5188 ko.templateSources = {}; 5189 5190 // ---- ko.templateSources.domElement ----- 5191 5192 ko.templateSources.domElement = function(element) { 5193 this.domElement = element; 5194 } 5195 5196 ko.templateSources.domElement.prototype['text'] = function(/* valueToWrite */) { 5197 var tagNameLower = ko.utils.tagNameLower(this.domElement), 5198 elemContentsProperty = tagNameLower === "script" ? "text" 5199 : tagNameLower === "textarea" ? "value" 5200 : "innerHTML"; 5201 5202 if (arguments.length == 0) { 5203 return this.domElement[elemContentsProperty]; 5204 } else { 5205 var valueToWrite = arguments[0]; 5206 if (elemContentsProperty === "innerHTML") 5207 ko.utils.setHtml(this.domElement, valueToWrite); 5208 else 5209 this.domElement[elemContentsProperty] = valueToWrite; 5210 } 5211 }; 5212 5213 ko.templateSources.domElement.prototype['data'] = function(key /*, valueToWrite */) { 5214 if (arguments.length === 1) { 5215 return ko.utils.domData.get(this.domElement, "templateSourceData_" + key); 5216 } else { 5217 ko.utils.domData.set(this.domElement, "templateSourceData_" + key, arguments[1]); 5218 } 5219 }; 5220 5221 // ---- ko.templateSources.anonymousTemplate ----- 5222 // Anonymous templates are normally saved/retrieved as DOM nodes through "nodes". 5223 // For compatibility, you can also read "text"; it will be serialized from the nodes on demand. 5224 // Writing to "text" is still supported, but then the template data will not be available as DOM nodes. 5225 5226 var anonymousTemplatesDomDataKey = "__ko_anon_template__"; 5227 ko.templateSources.anonymousTemplate = function(element) { 5228 this.domElement = element; 5229 } 5230 ko.templateSources.anonymousTemplate.prototype = new ko.templateSources.domElement(); 5231 ko.templateSources.anonymousTemplate.prototype.constructor = ko.templateSources.anonymousTemplate; 5232 ko.templateSources.anonymousTemplate.prototype['text'] = function(/* valueToWrite */) { 5233 if (arguments.length == 0) { 5234 var templateData = ko.utils.domData.get(this.domElement, anonymousTemplatesDomDataKey) || {}; 5235 if (templateData.textData === undefined && templateData.containerData) 5236 templateData.textData = templateData.containerData.innerHTML; 5237 return templateData.textData; 5238 } else { 5239 var valueToWrite = arguments[0]; 5240 ko.utils.domData.set(this.domElement, anonymousTemplatesDomDataKey, {textData: valueToWrite}); 5241 } 5242 }; 5243 ko.templateSources.domElement.prototype['nodes'] = function(/* valueToWrite */) { 5244 if (arguments.length == 0) { 5245 var templateData = ko.utils.domData.get(this.domElement, anonymousTemplatesDomDataKey) || {}; 5246 return templateData.containerData; 5247 } else { 5248 var valueToWrite = arguments[0]; 5249 ko.utils.domData.set(this.domElement, anonymousTemplatesDomDataKey, {containerData: valueToWrite}); 5250 } 5251 }; 5252
vendor: 4,152 bytes, lines 5253-5320
5253 ko.exportSymbol('templateSources', ko.templateSources); 5254 ko.exportSymbol('templateSources.domElement', ko.templateSources.domElement); 5255 ko.exportSymbol('templateSources.anonymousTemplate', ko.templateSources.anonymousTemplate); 5256})(); 5257(function () { 5258 var _templateEngine; 5259 ko.setTemplateEngine = function (templateEngine) { 5260 if ((templateEngine != undefined) && !(templateEngine instanceof ko.templateEngine)) 5261 throw new Error("templateEngine must inherit from ko.templateEngine"); 5262 _templateEngine = templateEngine; 5263 } 5264 5265 function invokeForEachNodeOrCommentInContinuousRange(firstNode, lastNode, action) { 5266 var node, nextInQueue = firstNode, firstOutOfRangeNode = ko.virtualElements.nextSibling(lastNode); 5267 while (nextInQueue && ((node = nextInQueue) !== firstOutOfRangeNode)) { 5268 nextInQueue = ko.virtualElements.nextSibling(node); 5269 if (node.nodeType === 1 || node.nodeType === 8) 5270 action(node); 5271 } 5272 } 5273 5274 function activateBindingsOnContinuousNodeArray(continuousNodeArray, bindingContext) { 5275 // To be used on any nodes that have been rendered by a template and have been inserted into some parent element 5276 // Walks through continuousNodeArray (which *must* be continuous, i.e., an uninterrupted sequence of sibling nodes, because 5277 // the algorithm for walking them relies on this), and for each top-level item in the virtual-element sense, 5278 // (1) Does a regular "applyBindings" to associate bindingContext with this node and to activate any non-memoized bindings 5279 // (2) Unmemoizes any memos in the DOM subtree (e.g., to activate bindings that had been memoized during template rewriting) 5280 5281 if (continuousNodeArray.length) { 5282 var firstNode = continuousNodeArray[0], lastNode = continuousNodeArray[continuousNodeArray.length - 1]; 5283 5284 // Need to applyBindings *before* unmemoziation, because unmemoization might introduce extra nodes (that we don't want to re-bind) 5285 // whereas a regular applyBindings won't introduce new memoized nodes 5286 invokeForEachNodeOrCommentInContinuousRange(firstNode, lastNode, function(node) { 5287 ko.applyBindings(bindingContext, node); 5288 }); 5289 invokeForEachNodeOrCommentInContinuousRange(firstNode, lastNode, function(node) { 5290 ko.memoization.unmemoizeDomNodeAndDescendants(node, [bindingContext]); 5291 }); 5292 } 5293 } 5294 5295 function getFirstNodeFromPossibleArray(nodeOrNodeArray) { 5296 return nodeOrNodeArray.nodeType ? nodeOrNodeArray 5297 : nodeOrNodeArray.length > 0 ? nodeOrNodeArray[0] 5298 : null; 5299 } 5300 5301 function executeTemplate(targetNodeOrNodeArray, renderMode, template, bindingContext, options) { 5302 options = options || {}; 5303 var firstTargetNode = targetNodeOrNodeArray && getFirstNodeFromPossibleArray(targetNodeOrNodeArray); 5304 var templateDocument = firstTargetNode && firstTargetNode.ownerDocument; 5305 var templateEngineToUse = (options['templateEngine'] || _templateEngine); 5306 ko.templateRewriting.ensureTemplateIsRewritten(template, templateEngineToUse, templateDocument); 5307 var renderedNodesArray = templateEngineToUse['renderTemplate'](template, bindingContext, options, templateDocument); 5308 5309 // Loosely check result is an array of DOM nodes 5310 if ((typeof renderedNodesArray.length != "number") || (renderedNodesArray.length > 0 && typeof renderedNodesArray[0].nodeType != "number")) 5311 throw new Error("Template engine must return an array of DOM nodes"); 5312 5313 var haveAddedNodesToParent = false; 5314 switch (renderMode) { 5315 case "replaceChildren": 5316 ko.virtualElements.setDomNodeChildren(targetNodeOrNodeArray, renderedNodesArray); 5317 haveAddedNodesToParent = true; 5318 break; 5319 case "replaceNode": 5320 ko.utils.replaceDomNodes(targetNodeOrNodeArray, renderedNodesArray);
5321 haveAddedNodesToParent = true; 5322 break; 5323 case "ignoreTargetNode": break; 5324 default: 5325 throw new Error("Unknown renderMode: " + renderMode); 5326 } 5327 5328 if (haveAddedNodesToParent) { 5329 activateBindingsOnContinuousNodeArray(renderedNodesArray, bindingContext); 5330 if (options['afterRender']) 5331 ko.dependencyDetection.ignore(options['afterRender'], null, [renderedNodesArray, bindingContext['$data']]); 5332 } 5333 5334 return renderedNodesArray; 5335 } 5336 5337 ko.renderTemplate = function (template, dataOrBindingContext, options, targetNodeOrNodeArray, renderMode) { 5338 options = options || {}; 5339 if ((options['templateEngine'] || _templateEngine) == undefined) 5340 throw new Error("Set a template engine before calling renderTemplate"); 5341 renderMode = renderMode || "replaceChildren"; 5342 5343 if (targetNodeOrNodeArray) { 5344 var firstTargetNode = getFirstNodeFromPossibleArray(targetNodeOrNodeArray); 5345 5346 var whenToDispose = function () { return (!firstTargetNode) || !ko.utils.domNodeIsAttachedToDocument(firstTargetNode); }; // Passive disposal (on next evaluation) 5347 var activelyDisposeWhenNodeIsRemoved = (firstTargetNode && renderMode == "replaceNode") ? firstTargetNode.parentNode : firstTargetNode; 5348 5349 return ko.dependentObservable( // So the DOM is automatically updated when any dependency changes 5350 function () { 5351 // Ensure we've got a proper binding context to work with 5352 var bindingContext = (dataOrBindingContext && (dataOrBindingContext instanceof ko.bindingContext)) 5353 ? dataOrBindingContext 5354 : new ko.bindingContext(ko.utils.unwrapObservable(dataOrBindingContext)); 5355 5356 // Support selecting template as a function of the data being rendered 5357 var templateName = typeof(template) == 'function' ? template(bindingContext['$data'], bindingContext) : template; 5358 5359 var renderedNodesArray = executeTemplate(targetNodeOrNodeArray, renderMode, templateName, bindingContext, options); 5360 if (renderMode == "replaceNode") { 5361 targetNodeOrNodeArray = renderedNodesArray; 5362 firstTargetNode = getFirstNodeFromPossibleArray(targetNodeOrNodeArray); 5363 } 5364 }, 5365 null, 5366 { disposeWhen: whenToDispose, disposeWhenNodeIsRemoved: activelyDisposeWhenNodeIsRemoved } 5367 ); 5368 } else { 5369 // We don't yet have a DOM node to evaluate, so use a memo and render the template later when there is a DOM node 5370 return ko.memoization.memoize(function (domNode) { 5371 ko.renderTemplate(template, dataOrBindingContext, options, domNode, "replaceNode"); 5372 }); 5373 } 5374 }; 5375 5376 ko.renderTemplateForEach = function (template, arrayOrObservableArray, options, targetNode, parentBindingContext) { 5377 // Since setDomNodeChildrenFromArrayMapping always calls executeTemplateForArrayItem and then 5378 // activateBindingsCallback for added items, we can store the binding context in the former to use in the latter. 5379 var arrayItemContext; 5380 5381 // This will be called by setDomNodeChildrenFromArrayMapping to get the nodes to add to targetNode 5382 var executeTemplateForArrayItem = function (arrayValue, index) { 5383 // Support selecting template as a function of the data being rendered 5384 arrayItemContext = parentBindingContext['createChildContext'](ko.utils.unwrapObservable(arrayValue), options['as']); 5385 arrayItemContext['$index'] = index; 5386 var templateName = typeof(template) == 'function' ? template(arrayValue, arrayItemContext) : template; 5387 return executeTemplate(null, "ignoreTargetNode", templateName, arrayItemContext, options); 5388 } 5389
5390 // This will be called whenever setDomNodeChildrenFromArrayMapping has added nodes to targetNode 5391 var activateBindingsCallback = function(arrayValue, addedNodesArray, index) { 5392 activateBindingsOnContinuousNodeArray(addedNodesArray, arrayItemContext); 5393 if (options['afterRender']) 5394 options['afterRender'](addedNodesArray, arrayValue); 5395 }; 5396 5397 return ko.dependentObservable(function () { 5398 var unwrappedArray = ko.utils.unwrapObservable(arrayOrObservableArray) || []; 5399 if (typeof unwrappedArray.length == "undefined") // Coerce single value into array 5400 unwrappedArray = [unwrappedArray]; 5401 5402 // Filter out any entries marked as destroyed 5403 var filteredArray = ko.utils.arrayFilter(unwrappedArray, function(item) { 5404 return options['includeDestroyed'] || item === undefined || item === null || !ko.utils.unwrapObservable(item['_destroy']); 5405 }); 5406 5407 // Call setDomNodeChildrenFromArrayMapping, ignoring any observables unwrapped within (most likely from a callback function). 5408 // If the array items are observables, though, they will be unwrapped in executeTemplateForArrayItem and managed within setDomNodeChildrenFromArrayMapping. 5409 ko.dependencyDetection.ignore(ko.utils.setDomNodeChildrenFromArrayMapping, null, [targetNode, filteredArray, executeTemplateForArrayItem, options, activateBindingsCallback]); 5410 5411 }, null, { disposeWhenNodeIsRemoved: targetNode }); 5412 }; 5413 5414 var templateComputedDomDataKey = '__ko__templateComputedDomDataKey__'; 5415 function disposeOldComputedAndStoreNewOne(element, newComputed) { 5416 var oldComputed = ko.utils.domData.get(element, templateComputedDomDataKey); 5417 if (oldComputed && (typeof(oldComputed.dispose) == 'function')) 5418 oldComputed.dispose(); 5419 ko.utils.domData.set(element, templateComputedDomDataKey, (newComputed && newComputed.isActive()) ? newComputed : undefined); 5420 } 5421 5422 ko.bindingHandlers['template'] = { 5423 'init': function(element, valueAccessor) { 5424 // Support anonymous templates 5425 var bindingValue = ko.utils.unwrapObservable(valueAccessor()); 5426 if ((typeof bindingValue != "string") && (!bindingValue['name']) && (element.nodeType == 1 || element.nodeType == 8)) { 5427 // It's an anonymous template - store the element contents, then clear the element 5428 var templateNodes = element.nodeType == 1 ? element.childNodes : ko.virtualElements.childNodes(element), 5429 container = ko.utils.moveCleanedNodesToContainerElement(templateNodes);
5429 // This also removes the nodes from their current parent 5430 new ko.templateSources.anonymousTemplate(element)['nodes'](container); 5431 } 5432 return { 'controlsDescendantBindings': true }; 5433 }, 5434 'update': function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 5435 var templateName = ko.utils.unwrapObservable(valueAccessor()), 5436 options = {}, 5437 shouldDisplay = true, 5438 dataValue, 5439 templateComputed = null; 5440 5441 if (typeof templateName != "string") { 5442 options = templateName; 5443 templateName = ko.utils.unwrapObservable(options['name']); 5444 5445 // Support "if"/"ifnot" conditions 5446 if ('if' in options) 5447 shouldDisplay = ko.utils.unwrapObservable(options['if']); 5448 if (shouldDisplay && 'ifnot' in options) 5449 shouldDisplay = !ko.utils.unwrapObservable(options['ifnot']); 5450 5451 dataValue = ko.utils.unwrapObservable(options['data']); 5452 } 5453 5454 if ('foreach' in options) { 5455 // Render once for each data point (treating data set as empty if shouldDisplay==false) 5456 var dataArray = (shouldDisplay && options['foreach']) || []; 5457 templateComputed = ko.renderTemplateForEach(templateName || element, dataArray, options, element, bindingContext); 5458 } else if (!shouldDisplay) { 5459 ko.virtualElements.emptyNode(element); 5460 } else { 5461 // Render once for this single data point (or use the viewModel if no data was provided) 5462 var innerBindingContext = ('data' in options) ? 5463 bindingContext['createChildContext'](dataValue, options['as']) : // Given an explitit 'data' value, we create a child binding context for it 5464 bindingContext; // Given no explicit 'data' value, we retain the same binding context 5465 templateComputed = ko.renderTemplate(templateName || element, innerBindingContext, options, element); 5466 } 5467 5468 // It only makes sense to have a single template computed per element (otherwise which one should have its output displayed?) 5469 disposeOldComputedAndStoreNewOne(element, templateComputed); 5470 } 5471 }; 5472 5473 // Anonymous templates can't be rewritten. Give a nice error message if you try to do it. 5474 ko.expressionRewriting.bindingRewriteValidators['template'] = function(bindingValue) { 5475 var parsedBindingValue = ko.expressionRewriting.parseObjectLiteral(bindingValue); 5476 5477 if ((parsedBindingValue.length == 1) && parsedBindingValue[0]['unknown']) 5478 return null; // It looks like a string literal, not an object literal, so treat it as a named template (which is allowed for rewriting) 5479 5480 if (ko.expressionRewriting.keyValueArrayContainsKey(parsedBindingValue, "name")) 5481 return null; // Named templates can be rewritten, so return "no error" 5482 return "This template engine does not support anonymous templates nested within its templates"; 5483 }; 5484 5485 ko.virtualElements.allowedBindings['template'] = true; 5486})(); 5487 5488ko.exportSymbol('setTemplateEngine', ko.setTemplateEngine); 5489ko.exportSymbol('renderTemplate', ko.renderTemplate); 5490 5491ko.utils.compareArrays = (function () { 5492 var statusNotInOld = 'added', statusNotInNew = 'deleted'; 5493 5494 // Simple calculation based on Levenshtein distance. 5495 function compareArrays(oldArray, newArray, dontLimitMoves) { 5496 oldArray = oldArray || []; 5497 newArray = newArray || []; 5498 5499 if (oldArray.length <= newArray.length) 5500 return compareSmallArrayToBigArray(oldArray, newArray, statusNotInOld, statusNotInNew, dontLimitMoves); 5501 else 5502 return compareSmallArrayToBigArray(newArray, oldArray, statusNotInNew, statusNotInOld, dontLimitMoves); 5503 } 5504 5505 function compareSmallArrayToBigArray(smlArray, bigArray, statusNotInSml, statusNotInBig, dontLimitMoves) { 5506 var myMin = Math.min, 5507 myMax = Math.max, 5508 editDistanceMatrix = [], 5509 smlIndex, smlIndexMax = smlArray.length, 5510 bigIndex, bigIndexMax = bigArray.length, 5511 compareRange = (bigIndexMax - smlIndexMax) || 1, 5512 maxDistance = smlIndexMax + bigIndexMax + 1, 5513 thisRow, lastRow, 5514 bigIndexMaxForRow, bigIndexMinForRow; 5515 5516 for (smlIndex = 0; smlIndex <= smlIndexMax; smlIndex++) { 5517 lastRow = thisRow; 5518 editDistanceMatrix.push(thisRow = []); 5519 bigIndexMaxForRow = myMin(bigIndexMax, smlIndex + compareRange); 5520 bigIndexMinForRow = myMax(0, smlIndex - 1); 5521 for (bigIndex = bigIndexMinForRow; bigIndex <= bigIndexMaxForRow; bigIndex++) { 5522 if (!bigIndex) 5523 thisRow[bigIndex] = smlIndex + 1; 5524 else if (!smlIndex) // Top row - transform empty array into new array via additions 5525 thisRow[bigIndex] = bigIndex + 1; 5526 else if (smlArray[smlIndex - 1] === bigArray[bigIndex - 1]) 5527 thisRow[bigIndex] = lastRow[bigIndex - 1]; // copy value (no edit) 5528 else { 5529 var northDistance = lastRow[bigIndex] || maxDistance; // not in big (deletion) 5530 var westDistance = thisRow[bigIndex - 1] || maxDistance; // not in small (addition) 5531 thisRow[bigIndex] = myMin(northDistance, westDistance) + 1; 5532 } 5533 } 5534 } 5535 5536 var editScript = [], meMinusOne, notInSml = [], notInBig = []; 5537 for (smlIndex = smlIndexMax, bigIndex = bigIndexMax; smlIndex || bigIndex;) { 5538 meMinusOne = editDistanceMatrix[smlIndex][bigIndex] - 1; 5539 if (bigIndex && meMinusOne === editDistanceMatrix[smlIndex][bigIndex-1]) { 5540 notInSml.push(editScript[editScript.length] = { // added 5541 'status': statusNotInSml, 5542 'value': bigArray[--bigIndex], 5543 'index': bigIndex }); 5544 } else if (smlIndex && meMinusOne === editDistanceMatrix[smlIndex - 1][bigIndex]) { 5545 notInBig.push(editScript[editScript.length] = { // deleted 5546 'status': statusNotInBig, 5547 'value': smlArray[--smlIndex], 5548 'index': smlIndex }); 5549 } else { 5550 editScript.push({ 5551 'status': "retained", 5552 'value': bigArray[--bigIndex] }); 5553 --smlIndex; 5554 } 5555 } 5556 5557 if (notInSml.length && notInBig.length) { 5558 // Set a limit on the number of consecutive non-matching comparisons; having it a multiple of 5559 // smlIndexMax keeps the time complexity of this algorithm linear. 5560 var limitFailedCompares = smlIndexMax * 10, failedCompares, 5561 a, d, notInSmlItem, notInBigItem; 5562 // Go through the items that have been added and deleted and try to find matches between them. 5563 for (failedCompares = a = 0; (dontLimitMoves || failedCompares < limitFailedCompares) && (notInSmlItem = notInSml[a]); a++) { 5564 for (d = 0; notInBigItem = notInBig[d]; d++) { 5565 if (notInSmlItem['value'] === notInBigItem['value']) { 5566 notInSmlItem['moved'] = notInBigItem['index']; 5567 notInBigItem['moved'] = notInSmlItem['index']; 5568 notInBig.splice(d,1); // This item is marked as moved; so remove it from notInBig list 5569 failedCompares = d = 0; // Reset failed compares count because we're checking for consecutive failures 5570 break; 5571 } 5572 } 5573 failedCompares += d; 5574 } 5575 } 5576 return editScript.reverse(); 5577 } 5578 5579 return compareArrays; 5580})(); 5581 5582ko.exportSymbol('utils.compareArrays', ko.utils.compareArrays); 5583 5584(function () { 5585 // Objective: 5586 // * Given an input array, a container DOM node, and a function from array elements to arrays of DOM nodes, 5587 // map the array elements to arrays of DOM nodes, concatenate together all these arrays, and use them to populate the container DOM node 5588 // * Next time we're given the same combination of things (with the array possibly having mutated), update the container DOM node 5589 // so that its children is again the concatenation of the mappings of the array elements, but don't re-map any array elements that we 5590 // previously mapped - retain those nodes, and just insert/delete other ones 5591 5592 // "callbackAfterAddingNodes" will be invoked after any "mapping"-generated nodes are inserted into the container node 5593 // You can use this, for example, to activate bindings on those nodes. 5594 5595 function fixUpNodesToBeMovedOrRemoved(contiguousNodeArray) { 5596 // Before moving, deleting, or replacing a set of nodes that were previously outputted by the "map" function, we have to reconcile 5597 // them against what is in the DOM right now. It may be that some of the nodes have already been removed from the document, 5598 // or that new nodes might have been inserted in the middle, for example by a binding. Also, there may previously have been 5599 // leading comment nodes (created by rewritten string-based templates) that have since been removed during binding. 5600 // So, this function translates the old "map" output array into its best guess of what set of current DOM nodes should be removed. 5601 // 5602 // Rules: 5603 // [A] Any leading nodes that aren't in the document any more should be ignored 5604 // These most likely correspond to memoization nodes that were already removed during binding 5605 // See https://github.com/SteveSanderson/knockout/pull/440 5606 // [B] We want to output a contiguous series of nodes that are still in the document. So, ignore any nodes that 5607 // have already been removed, and include any nodes that have been inserted among the previous collection 5608 5609 // Rule [A] 5610 while (contiguousNodeArray.length && !ko.utils.domNodeIsAttachedToDocument(contiguousNodeArray[0])) 5611 contiguousNodeArray.splice(0, 1); 5612 5613 // Rule [B] 5614 if (contiguousNodeArray.length > 1) { 5615 // Build up the actual new contiguous node set 5616 var current = contiguousNodeArray[0], last = contiguousNodeArray[contiguousNodeArray.length - 1], newContiguousSet = [current]; 5617 while (current !== last) { 5618 current = current.nextSibling; 5619 if (!current) // Won't happen, except if the developer has manually removed some DOM elements (then we're in an undefined scenario) 5620 return; 5621 newContiguousSet.push(current); 5622 } 5623 5624 // ... then mutate the input array to match this. 5625 // (The following line replaces the contents of contiguousNodeArray with
5625newContiguousSet) 5626 Array.prototype.splice.apply(contiguousNodeArray, [0, contiguousNodeArray.length].concat(newContiguousSet)); 5627 } 5628 return contiguousNodeArray; 5629 } 5630 5631 function mapNodeAndRefreshWhenChanged(containerNode, mapping, valueToMap, callbackAfterAddingNodes, index) { 5632 // Map this array value inside a dependentObservable so we re-map when any dependency changes 5633 var mappedNodes = []; 5634 var dependentObservable = ko.dependentObservable(function() { 5635 var newMappedNodes = mapping(valueToMap, index, fixUpNodesToBeMovedOrRemoved(mappedNodes)) || []; 5636 5637 // On subsequent evaluations, just replace the previously-inserted DOM nodes 5638 if (mappedNodes.length > 0) { 5639 ko.utils.replaceDomNodes(mappedNodes, newMappedNodes); 5640 if (callbackAfterAddingNodes) 5641 ko.dependencyDetection.ignore(callbackAfterAddingNodes, null, [valueToMap, newMappedNodes, index]); 5642 } 5643 5644 // Replace the contents of the mappedNodes array, thereby updating the record 5645 // of which nodes would be deleted if valueToMap was itself later removed 5646 mappedNodes.splice(0, mappedNodes.length); 5647 ko.utils.arrayPushAll(mappedNodes, newMappedNodes); 5648 }, null, { disposeWhenNodeIsRemoved: containerNode, disposeWhen: function() { return !ko.utils.anyDomNodeIsAttachedToDocument(mappedNodes); } }); 5649 return { mappedNodes : mappedNodes, dependentObservable : (dependentObservable.isActive() ? dependentObservable : undefined) }; 5650 } 5651 5652 var lastMappingResultDomDataKey = "setDomNodeChildrenFromArrayMapping_lastMappingResult"; 5653 5654 ko.utils.setDomNodeChildrenFromArrayMapping = function (domNode, array, mapping, options, callbackAfterAddingNodes) { 5655 // Compare the provided array against the previous one 5656 array = array || []; 5657 options = options || {}; 5658 var isFirstExecution = ko.utils.domData.get(domNode, lastMappingResultDomDataKey) === undefined; 5659 var lastMappingResult = ko.utils.domData.get(domNode, lastMappingResultDomDataKey) || []; 5660 var lastArray = ko.utils.arrayMap(lastMappingResult, function (x) { return x.arrayEntry; }); 5661 var editScript = ko.utils.compareArrays(lastArray, array, options['dontLimitMoves']); 5662 5663 // Build the new mapping result 5664 var newMappingResult = []; 5665 var lastMappingResultIndex = 0; 5666 var newMappingResultIndex = 0; 5667 5668 var nodesToDelete = []; 5669 var itemsToProcess = []; 5670 var itemsForBeforeRemoveCallbacks = []; 5671 var itemsForMoveCallbacks = []; 5672 var itemsForAfterAddCallbacks = []; 5673 var mapData; 5674 5675 function itemMovedOrRetained(editScriptIndex, oldPosition) { 5676 mapData = lastMappingResult[oldPosition]; 5677 if (newMappingResultIndex !== oldPosition) 5678 itemsForMoveCallbacks[editScriptIndex] = mapData; 5679 // Since updating the index might change the nodes, do so before calling fixUpNodesToBeMovedOrRemoved 5680 mapData.indexObservable(newMappingResultIndex++); 5681 fixUpNodesToBeMovedOrRemoved(mapData.mappedNodes); 5682 newMappingResult.push(mapData); 5683 itemsToProcess.push(mapData); 5684 } 5685 5686 function callCallback(callback, items) { 5687 if (callback) { 5688 for (var i = 0, n = items.length; i < n; i++) { 5689 if (items[i]) { 5690 ko.utils.arrayForEach(items[i].mappedNodes, function(node) { 5691 callback(node, i, items[i].arrayEntry); 5692 }); 5693 } 5694 } 5695 } 5696 } 5697 5698 for (var i = 0, editScriptItem, movedIndex; editScriptItem = editScript[i]; i++) { 5699 movedIndex = editScriptItem['moved']; 5700 switch (editScriptItem['status']) { 5701 case "deleted": 5702 if (movedIndex === undefined) { 5703 mapData = lastMappingResult[lastMappingResultIndex]; 5704 5705 // Stop tracking changes to the mapping for these nodes 5706 if (mapData.dependentObservable) 5707 mapData.dependentObservable.dispose(); 5708 5709 // Queue these nodes for later removal 5710 nodesToDelete.push.apply(nodesToDelete, fixUpNodesToBeMovedOrRemoved(mapData.mappedNodes)); 5711 if (options['beforeRemove']) { 5712 itemsForBeforeRemoveCallbacks[i] = mapD
5712ata; 5713 itemsToProcess.push(mapData); 5714 } 5715 } 5716 lastMappingResultIndex++; 5717 break; 5718 5719 case "retained": 5720 itemMovedOrRetained(i, lastMappingResultIndex++); 5721 break; 5722 5723 case "added": 5724 if (movedIndex !== undefined) { 5725 itemMovedOrRetained(i, movedIndex); 5726 } else { 5727 mapData = { arrayEntry: editScriptItem['value'], indexObservable: ko.observable(newMappingResultIndex++) }; 5728 newMappingResult.push(mapData); 5729 itemsToProcess.push(mapData); 5730 if (!isFirstExecution) 5731 itemsForAfterAddCallbacks[i] = mapData; 5732 } 5733 break; 5734 } 5735 } 5736 5737 // Call beforeMove first before any changes have been made to the DOM 5738 callCallback(options['beforeMove'], itemsForMoveCallbacks); 5739 5740 // Next remove nodes for deleted items (or just clean if there's a beforeRemove callback) 5741 ko.utils.arrayForEach(nodesToDelete, options['beforeRemove'] ? ko.cleanNode : ko.removeNode); 5742 5743 // Next add/reorder the remaining items (will include deleted items if there's a beforeRemove callback) 5744 for (var i = 0, nextNode = ko.virtualElements.firstChild(domNode), lastNode, node; mapData = itemsToProcess[i]; i++) { 5745 // Get nodes for newly added items 5746 if (!mapData.mappedNodes) 5747 ko.utils.extend(mapData, mapNodeAndRefreshWhenChanged(domNode, mapping, mapData.arrayEntry, callbackAfterAddingNodes, mapData.indexObservable)); 5748 5749 // Put nodes in the right place if they aren't there already 5750 for (var j = 0; node = mapData.mappedNodes[j]; nextNode = node.nextSibling, lastNode = node, j++) { 5751 if (node !== nextNode) 5752 ko.virtualElements.insertAfter(domNode, node, lastNode); 5753 } 5754 5755 // Run the callbacks for newly added nodes (for example, to apply bindings, etc.) 5756 if (!mapData.initialized && callbackAfterAddingNodes) { 5757 callbackAfterAddingNodes(mapData.arrayEntry, mapData.mappedNodes, mapData.indexObservable); 5758 mapData.initialized = true; 5759 } 5760 } 5761 5762 // If there's a beforeRemove callback, call it after reordering. 5763 // Note that we assume that the beforeRemove callback will usually be used to remove the nodes using 5764 // some sort of animation, which is why we first reorder the nodes that will be removed. If the 5765 // callback instead removes the nodes right away, it would be more efficient to skip reordering them. 5766 // Perhaps we'll make that change in the future if this scenario becomes more common. 5767 callCallback(options['beforeRemove'], itemsForBeforeRemoveCallbacks); 5768 5769 // Finally call afterMove and afterAdd callbacks 5770 callCallback(options['afterMove'], itemsForMoveCallbacks); 5771 callCallback(options['afterAdd'], itemsForAfterAddCallbacks); 5772 5773 // Store a copy of the array items we just considered so we can difference it next time 5774 ko.utils.domData.set(domNode, lastMappingResultDomDataKey, newMappingResult); 5775 } 5776})(); 5777 5778ko.exportSymbol('utils.setDomNodeChildrenFromArrayMapping', ko.utils.setDomNodeChildrenFromArrayMapping); 5779ko.nativeTemplateEngine = function () { 5780 this['allowTemplateRewriting'] = false; 5781} 5782 5783ko.nativeTemplateEngine.prototype = new ko.templateEngine(); 5784ko.nativeTemplateEngine.prototype.constructor = ko.nativeTemplateEngine; 5785ko.nativeTemplateEngine.prototype['renderTemplateSource'] = function (templateSource, bindingContext, options) { 5786 var useNodesIfAvailable = !(ko.utils.ieVersion < 9), // IE<9 cloneNode doesn't work properly 5787 templateNodesFunc = useNodesIfAvailable ? templateSource['nodes'] : null, 5788 templateNodes = templateNodesFunc ? templateSource['nodes']() : null; 5789 5790 if (templateNodes) { 5791 return ko.utils.makeArray(templateNodes.cloneNode(true).childNodes); 5792 } else { 5793 var templateText = templateSource['text'](); 5794 return ko.utils.parseHtmlFragment(templateText); 5795 } 5796}; 5797 5798ko.nativeTemplateEngine.instance = new ko.nativeTemplateEngine(); 5799ko.setTemplateEngine(ko.nativeTemplateEngine.instance); 5800 5801ko.exportSymbol('nativeTemplateEngine', ko.nativeTemplateEngine); 5802(function() { 5803 ko.jqueryTmplTemplateEngine = function () { 5804 // Detect which version of jquery-tmpl you're using. Unfortunately jquery-tmpl 5805 // doesn't expose a version number, so we have to infer it. 5806 // Note that as of Knockout 1.3, we only support jQuery.tmpl 1.0.0pre and later, 5807 // which KO internally refers to as version "2", so older versions are no longer detected. 5808 var jQueryTmplVersion = this.jQueryTmplVersion = (function() { 5809 if ((typeof(jQuery) == "undefined") || !(jQuery['tmpl'])) 5810 return 0; 5811 // Since it exposes no official version number, we use our own numbering system. To be updated as jquery-tmpl evolves. 5812 try { 5813 if (jQuery['tmpl']['tag']['tmpl']['open'].toString().indexOf('__') >= 0) { 5814 // Since 1.0.0pre, custom tags should append markup to an array called "__" 5815 return 2; // Final version of jquery.tmpl 5816 } 5817 } catch(ex) { /* Apparently not the version we were looking for */ } 5818 5819 return 1; // Any older version that we don't support 5820 })(); 5821 5822 function ensureHasReferencedJQueryTemplates() { 5823 if (jQueryTmplVersion < 2) 5824 throw new Error("Your version of jQuery.tmpl is too old. Please upgrade to jQuery.tmpl 1.0.0pre or later."); 5825 } 5826 5827 function executeTemplate(compiledTemplate, data, jQueryTemplateOptions) { 5828 return jQuery['tmpl'](compiledTemplate, data, jQueryTemplateOptions); 5829 } 5830 5831 this['renderTemplateSource'] = function(templateSource, bindingContext, options) { 5832 options = options || {}; 5833 ensureHasReferencedJQueryTemplates(); 5834 5835 // Ensure we have stored a precompiled version of this template (don't want to reparse on every render) 5836 var precompiled = templateSource['data']('precompiled'); 5837 if (!precompiled) { 5838 var templateText = templateSource['text']() || ""; 5839 // Wrap in "with($whatever.koBindingContext) { ... }" 5840 templateText = "{{ko_with $item.koBindingContext}}" + templateText + "{{/ko_with}}"; 5841 5842 precompiled = jQuery['template'](null, templateText); 5843 templateSource['data']('precompiled', precompiled); 5844 } 5845 5846 var data = [bindingContext['$data']]; // Prewrap the data in an array to stop jquery.tmpl from trying to unwrap any arrays 5847 var jQueryTemplateOptions = jQuery['extend']({ 'koBindingContext': bindingContext }, options['templateOptions']); 5848 5849 var resultNodes = executeTemplate(precompiled, data, jQueryTemplateOptions); 5850 resultNodes['appendTo'](document.createElement("div")); // Using "appendTo" forces jQuery/jQuery.tmpl to perform necessary cleanup work 5851 5852 jQuery['fragments'] = {}; // Clear jQuery's fragment cache to avoid a memory leak after a large number of template renders 5853 return resultNodes; 5854 }; 5855
5856 this['createJavaScriptEvaluatorBlock'] = function(script) { 5857 return "{{ko_code ((function() { return " + script + " })()) }}"; 5858 }; 5859 5860 this['addTemplate'] = function(templateName, templateMarkup) { 5861 document.write("<script type='text/html' id='" + templateName + "'>" + templateMarkup + "<" + "/script>"); 5862 }; 5863 5864 if (jQueryTmplVersion > 0) { 5865 jQuery['tmpl']['tag']['ko_code'] = { 5866 open: "__.push($1 || '');" 5867 }; 5868 jQuery['tmpl']['tag']['ko_with'] = { 5869 open: "with($1) {", 5870 close: "} " 5871 }; 5872 } 5873 }; 5874 5875 ko.jqueryTmplTemplateEngine.prototype = new ko.templateEngine(); 5876 ko.jqueryTmplTemplateEngine.prototype.constructor = ko.jqueryTmplTemplateEngine; 5877 5878 // Use this one by default *only if jquery.tmpl is referenced* 5879 var jqueryTmplTemplateEngineInstance = new ko.jqueryTmplTemplateEngine(); 5880 if (jqueryTmplTemplateEngineInstance.jQueryTmplVersion > 0) 5881 ko.setTemplateEngine(jqueryTmplTemplateEngineInstance); 5882 5883 ko.exportSymbol('jqueryTmplTemplateEngine', ko.jqueryTmplTemplateEngine); 5884})(); 5885})); 5886}()); 5887})(); 5888 5889 5890; 5891////pf: javascript/clndr.js 5892/* 5893 * ~ CLNDR v1.2.0 ~ 5894 * ============================================== 5895 * https://github.com/kylestetz/CLNDR 5896 * ============================================== 5897 * created by kyle stetz (github.com/kylestetz) 5898 * &available under the MIT license 5899 * http://opensource.org/licenses/mit-license.php 5900 * ============================================== 5901 * 5902 * This is the fully-commented development version of CLNDR. 5903 * For the production version, check out clndr.min.js 5904 * at https://github.com/kylestetz/CLNDR 5905 * 5906 * This work is based on the 5907 * jQuery lightweight plugin boilerplate 5908 * Original author: @ajpiano 5909 * Further changes, comments: @addyosmani 5910 * Licensed under the MIT license 5911 */ 5912 5913;(function ( $, window, document, undefined ) { 5914 5915 // This is the default calendar template. This can be overridden. 5916 var clndrTemplate = "<div class='clndr-controls'>" + 5917 "<div class='clndr-control-button'><span class='clndr-previous-button'>previous</span></div><div class='month'><%= month %> <%= year %></div><div class='clndr-control-button rightalign'><span class='clndr-next-button'>next</span></div>" + 5918 "</div>" + 5919 "<table class='clndr-table' border='0' cellspacing='0' cellpadding='0'>" + 5920 "<thead>" + 5921 "<tr class='header-days'>" + 5922 "<% for(var i = 0; i < daysOfTheWeek.length; i++) { %>" + 5923 "<td class='header-day'><%= daysOfTheWeek[i] %></td>" + 5924 "<% } %>" + 5925 "</tr>" + 5926 "</thead>" + 5927 "<tbody>" + 5928 "<% for(var i = 0; i < numberOfRows; i++){ %>" + 5929 "<tr>" + 5930 "<% for(var j = 0; j < 7; j++){ %>" + 5931 "<% var d = j + i * 7; %>" + 5932 "<td class='<%= days[d].classes %>'><div class='day-contents'><%= days[d].day %>" + 5933 "</div></td>" + 5934 "<% } %>" + 5935 "</tr>" + 5936 "<% } %>" + 5937 "</tbody>" + 5938 "</table>"; 5939 5940 var pluginName = 'clndr'; 5941 5942 var defaults = { 5943 template: clndrTemplate, 5944 weekOffset: 0, 5945 startWithMonth: null, 5946 clickEvents: { 5947 click: null, 5948 nextMonth: null, 5949 previousMonth: null, 5950 nextYear: null, 5951 previousYear: null, 5952 today: null, 5953 onMonthChange: null, 5954 onYearChange: null 5955 }, 5956 targets: { 5957 nextButton: 'clndr-next-button', 5958 previousButton: 'clndr-previous-button', 5959 nextYearButton: 'clndr-next-year-button', 5960 previousYearButton: 'clndr-previous-year-button', 5961 todayButton: 'clndr-today-button', 5962 day: 'day', 5963 empty: 'empty' 5964 }, 5965 events: [], 5966 extras: null, 5967 dateParameter: 'date', 5968 multiDayEvents: null, 5969 doneRendering: null, 5970 render: null, 5971 daysOfTheWeek: null, 5972 showAdjacentMonths: true, 5973 adjacentDaysChangeMonth: false, 5974 ready: null, 5975 constraints: null, 5976 forceSixRows: null 5977 }; 5978 5979 // The actual plugin constructor 5980 function Clndr( element, options ) { 5981 this.element = element; 5982
5983 // merge the default options with user-provided options 5984 this.options = $.extend(true, {}, defaults, options); 5985 5986 // if there are events, we should run them through our addMomentObjectToEvents function 5987 // which will add a date object that we can use to make life easier. This is only necessary 5988 // when events are provided on instantiation, since our setEvents function uses addMomentObjectToEvents. 5989 if(this.options.events.length) { 5990 if(this.options.multiDayEvents) { 5991 this.options.events = this.addMultiDayMomentObjectsToEvents(this.options.events); 5992 } else { 5993 this.options.events = this.addMomentObjectToEvents(this.options.events); 5994 } 5995 } 5996 5997 // this object will store a reference to the current month. 5998 // it's a moment object, which allows us to poke at it a little if we need to. 5999 // this will serve as the basis for switching between months & is the go-to 6000 // internally if we want to know which month we're currently at. 6001 if(this.options.startWithMonth) { 6002 this.month = moment(this.options.startWithMonth).startOf('month'); 6003 } else { 6004 this.month = moment().startOf('month'); 6005 } 6006 6007 // if we've got constraints set, make sure the month is within them. 6008 if(this.options.constraints) { 6009 // first check if the start date exists & is later than now. 6010 if(this.options.constraints.startDate) { 6011 var startMoment = moment(this.options.constraints.startDate); 6012 if(this.month.isBefore(startMoment, 'month')) { 6013 this.month.set('month', startMoment.month()); 6014 this.month.set('year', startMoment.year()); 6015 } 6016 } 6017 // make sure the month (whether modified or not) is before the endDate 6018 if(this.options.constraints.endDate) { 6019 var endMoment = moment(this.options.constraints.endDate); 6020 if(this.month.isAfter(endMoment, 'month')) { 6021 this.month.set('month', endMoment.month()).set('year', endMoment.year()); 6022 } 6023 } 6024 } 6025 6026 this._defaults = defaults; 6027 this._name = pluginName; 6028 6029 // Some first-time initialization -> day of the week offset, 6030 // template compiling, making and storing some elements we'll need later, 6031 // & event handling for the controller. 6032 this.init(); 6033 } 6034 6035 Clndr.prototype.init = function () { 6036 // create the days of the week using moment's current language setting 6037 this.daysOfTheWeek = this.options.daysOfTheWeek || []; 6038 if(!this.options.daysOfTheWeek) { 6039 this.daysOfTheWeek = []; 6040 for(var i = 0; i < 7; i++) { 6041 this.daysOfTheWeek.push( moment().weekday(i).format('dd').charAt(0) ); 6042 } 6043 } 6044 // shuffle the week if there's an offset 6045 if(this.options.weekOffset) { 6046 this.daysOfTheWeek = this.shiftWeekdayLabels(this.options.weekOffset); 6047 } 6048 6049 // quick & dirty test to make sure rendering is possible. 6050 if( !$.isFunction(this.options.render) ) { 6051 this.options.render = null; 6052 if (typeof _ === 'undefined') { 6053 throw new Error("Underscore was not found. Please include underscore.js OR provide a custom render function."); 6054 } 6055 else { 6056 // we're just going ahead and using underscore here if no render method has been supplied. 6057 this.compiledClndrTemplate = _.template(this.options.template); 6058 } 6059 } 6060 6061 // create the parent element that will hold the plugin & save it for later 6062 $(this.element).html("<div class='clndr'></div>"); 6063 this.calendarContainer = $('.clndr', this.element); 6064 6065 // attach event handlers for clicks on buttons/cells 6066 this.bindEvents(); 6067 6068 // do a normal render of the calendar template 6069 this.render(); 6070 6071 // if a ready callback has been provided, call it. 6072 if(this.options.ready) { 6073 this.options.ready.apply(this, []); 6074 } 6075 }; 6076 6077 Clndr.prototype.shiftWeekdayLabels = function(offset) { 6078 var days = this.daysOfTheWeek; 6079 for(var i = 0; i < offset; i++) { 6080 days.push( days.shift() ); 6081 } 6082 return days; 6083 }; 6084 6085 // This is where the magic happens. Given a moment object representing the current month, 6086 // an array of calendarDay objects is constructed that contains appropriate events and
6087 // classes depending on the circumstance. 6088 Clndr.prototype.createDaysObject = function(currentMonth) { 6089 // this array will hold numbers for the entire grid (even the blank spaces) 6090 daysArray = []; 6091 var date = currentMonth.startOf('month'); 6092 6093 // filter the events list (if it exists) to events that are happening last month, this month and next month (within the current grid view) 6094 this.eventsLastMonth = []; 6095 this.eventsThisMonth = []; 6096 this.eventsNextMonth = []; 6097 6098 if(this.options.events.length) { 6099 6100 // MULTI-DAY EVENT PARSING 6101 // if we're using multi-day events, the start or end must be in the current month 6102 if(this.options.multiDayEvents) { 6103 this.eventsThisMonth = $(this.options.events).filter( function() { 6104 return this._clndrStartDateObject.format("YYYY-MM") <= currentMonth.format("YYYY-MM") 6105 || currentMonth.format("YYYY-MM") <= this._clndrEndDateObject.format("YYYY-MM"); 6106 }).toArray(); 6107 6108 if(this.options.showAdjacentMonths) { 6109 var lastMonth = currentMonth.clone().subtract('months', 1); 6110 var nextMonth = currentMonth.clone().add('months', 1); 6111 this.eventsLastMonth = $(this.options.events).filter( function() { 6112 return this._clndrStartDateObject.format("YYYY-MM") <= lastMonth.format("YYYY-MM") 6113 || lastMonth.format("YYYY-MM") <= this._clndrEndDateObject.format("YYYY-MM"); 6114 }).toArray(); 6115 6116 this.eventsNextMonth = $(this.options.events).filter( function() { 6117 return this._clndrStartDateObject.format("YYYY-MM") <= nextMonth.format("YYYY-MM") 6118 || nextMonth.format("YYYY-MM") <= this._clndrEndDateObject.format("YYYY-MM"); 6119 }).toArray(); 6120 } 6121 } 6122 6123 // SINGLE-DAY EVENT PARSING 6124 // if we're using single-day events, use _clndrDateObject 6125 else { 6126 this.eventsThisMonth = $(this.options.events).filter( function() { 6127 return this._clndrDateObject.format("YYYY-MM") == currentMonth.format("YYYY-MM"); 6128 }).toArray(); 6129 6130 // filter the adjacent months as well, if the option is true 6131 if(this.options.showAdjacentMonths) { 6132 var lastMonth = currentMonth.clone().subtract('months', 1); 6133 var nextMonth = currentMonth.clone().add('months', 1); 6134 this.eventsLastMonth = $(this.options.events).filter( function() { 6135 return this._clndrDateObject.format("YYYY-MM") == lastMonth.format("YYYY-MM"); 6136 }).toArray(); 6137 6138 this.eventsNextMonth = $(this.options.events).filter( function() { 6139 return this._clndrDateObject.format("YYYY-MM") == nextMonth.format("YYYY-MM"); 6140 }).toArray(); 6141 } 6142 } 6143 } 6144 6145 // if diff is greater than 0, we'll have to fill in last days of the previous month 6146 // to account for the empty boxes in the grid. 6147 // we also need to take into account the weekOffset parameter 6148 var diff = date.weekday() - this.options.weekOffset; 6149 if(diff < 0) diff += 7; 6150 6151 if(this.options.showAdjacentMonths) { 6152 for(var i = 0; i < diff; i++) { 6153 var day = moment([currentMonth.year(), currentMonth.month(), i - diff + 1]); 6154 daysArray.push( this.createDayObject(day, this.eventsLastMonth) ); 6155 } 6156 } else { 6157 for(var i = 0; i < diff; i++) { 6158 daysArray.push( this.calendarDay({ classes: this.options.targets.empty + " last-month" }) ); 6159 } 6160 } 6161 6162 // now we push all of the days in a month 6163 var numOfDays = date.daysInMonth(); 6164 for(var i = 1; i <= numOfDays; i++) { 6165 var day = moment([currentMonth.year(), currentMonth.month(), i]); 6166 daysArray.push(this.createDayObject(day, this.eventsThisMonth) ) 6167 } 6168 6169 // ...and if there are any trailing blank boxes, fill those in 6170 // with the next month first days 6171 var i = 1; 6172 while(daysArray.length % 7 !== 0) { 6173 if(this.options.showAdjacentMonths) { 6174 var day = moment([currentMonth.year(), currentMonth.month(), numOfDays + i]); 6175 daysArray.push( this.createDayObject(day, this.eventsNextMonth) ); 6176 } else { 6177 daysArray.push( this.calendarDay({ classes: this.options.targets.empty + " next-month" }) ); 6178 } 6179 i++; 6180 } 6181 6182 // if we want to force six rows of calendar, now's our last chance to add another row. 6183 // if the 42 seems explicit it's because we're creating a 7-row grid and 6 rows of 7 is always 42! 6184 if(this.options.forceSixRows && daysArray.length !== 42 ) { 6185 var start = moment(daysArray[daysArray.length - 1].date).add('days', 1); 6186 while(daysArray.length < 42) { 6187 if(this.options.showAdjacentMonths) { 6188 daysArray.push( this.createDayObject(moment(start), this.eventsNextMonth) ); 6189 start.add('days', 1); 6190 } else { 6191 daysArray.push( this.calendarDay({ classes: this.options.targets.empty + " next-month" }) ); 6192 } 6193 } 6194 } 6195 6196 return daysArray; 6197 }; 6198 6199 Clndr.prototype.createDayObject = function(day, monthEvents) { 6200 var eventsToday = []; 6201 var now = moment(); 6202 var self = this; 6203 6204 var j = 0, l = monthEvents.length; 6205 for(j; j < l; j++) { 6206 // keep in mind that the events here already passed the month/year test. 6207 // now all we have to compare is the moment.date(), which returns the day of the month. 6208 if(self.options.multiDayEvents) { 6209 var start = monthEvents[j]._clndrStartDateObject; 6210 var end = monthEvents[j]._clndrEndDateObject; 6211 // if today is the same day as start or is after the start, and 6212 // if today is the same day as the end or before the end ... 6213 // woohoo semantics! 6214 if( ( day.isSame(start, 'day') || day.isAfter(start, 'day') ) && 6215 ( day.isSame(end, 'day') || day.isBefore(end, 'day') ) ) { 6216 eventsToday.push( monthEvents[j] ); 6217 } 6218 } else { 6219 if( monthEvents[j]._clndrDateObject.date() == day.date() ) { 6220 eventsToday.push( monthEvents[j] ); 6221 } 6222 } 6223 } 6224
6225 var extraClasses = ""; 6226 6227 if(now.format("YYYY-MM-DD") == day.format("YYYY-MM-DD")) { 6228 extraClasses += " today"; 6229 } 6230 if(day.isBefore(now, 'day')) { 6231 extraClasses += " past"; 6232 } 6233 if(eventsToday.length) { 6234 extraClasses += " event"; 6235 } 6236 if(this.month.month() > day.month()) { 6237 extraClasses += " adjacent-month"; 6238 6239 this.month.year() === day.year() 6240 ? extraClasses += " last-month" 6241 : extraClasses += " next-month"; 6242 6243 } else if(this.month.month() < day.month()) { 6244 extraClasses += " adjacent-month"; 6245 6246 this.month.year() === day.year() 6247 ? extraClasses += " next-month" 6248 : extraClasses += " last-month"; 6249 } 6250 6251 // if there are constraints, we need to add the inactive class to the days outside of them 6252 if(this.options.constraints) { 6253 if(this.options.constraints.startDate && day.isBefore(moment( this.options.constraints.startDate ))) { 6254 extraClasses += " inactive"; 6255 } 6256 if(this.options.constraints.endDate && day.isAfter(moment( this.options.constraints.endDate ))) { 6257 extraClasses += " inactive"; 6258 } 6259 } 6260 6261 // validate moment date 6262 if (!day.isValid() && day.hasOwnProperty('_d') && day._d != undefined) { 6263 day = moment(day._d); 6264 } 6265 6266 // we're moving away from using IDs in favor of classes, since when 6267 // using multiple calendars on a page we are technically violating the 6268 // uniqueness of IDs. 6269 extraClasses += " calendar-day-" + day.format("YYYY-MM-DD"); 6270 6271 // day of week 6272 extraClasses += " calendar-dow-" + day.weekday(); 6273 6274 return this.calendarDay({ 6275 day: day.date(), 6276 classes: this.options.targets.day + extraClasses, 6277 events: eventsToday, 6278 date: day 6279 }); 6280 }; 6281 6282 Clndr.prototype.render = function() { 6283 // get rid of the previous set of calendar parts.
6284 // TODO: figure out if this is the right way to ensure proper garbage collection? 6285 this.calendarContainer.children().remove(); 6286 // get an array of days and blank spaces 6287 var days = this.createDaysObject(this.month); 6288 // this is to prevent a scope/naming issue between this.month and data.month 6289 var currentMonth = this.month; 6290 6291 var data = { 6292 daysOfTheWeek: this.daysOfTheWeek, 6293 numberOfRows: Math.ceil(days.length / 7), 6294 days: days, 6295 month: this.month.format('MMMM'), 6296 year: this.month.year(), 6297 eventsThisMonth: this.eventsThisMonth, 6298 eventsLastMonth: this.eventsLastMonth, 6299 eventsNextMonth: this.eventsNextMonth, 6300 extras: this.options.extras 6301 }; 6302 6303 // render the calendar with the data above & bind events to its elements 6304 if(!this.options.render) { 6305 this.calendarContainer.html(this.compiledClndrTemplate(data)); 6306 } else { 6307 this.calendarContainer.html(this.options.render.apply(this, [data])); 6308 } 6309 6310 // if there are constraints, we need to add the 'inactive' class to the controls 6311 if(this.options.constraints) { 6312 // in the interest of clarity we're just going to remove all inactive classes and re-apply them each render. 6313 for(target in this.options.targets) { 6314 if(target != this.options.targets.day) { 6315 this.element.find('.' + this.options.targets[target]).toggleClass('inactive', false); 6316 } 6317 } 6318 6319 var start = null; 6320 var end = null; 6321 6322 if(this.options.constraints.startDate) { 6323 start = moment(this.options.constraints.startDate); 6324 } 6325 if(this.options.constraints.endDate) { 6326 end = moment(this.options.constraints.endDate); 6327 } 6328 // deal with the month controls first. 6329 // are we at the start month? 6330 if(start && this.month.isSame( start, 'month' )) { 6331 this.element.find('.' + this.options.targets.previousButton).toggleClass('inactive', true); 6332 } 6333 // are we at the end month? 6334 if(end && this.month.isSame( end, 'month' )) { 6335 this.element.find('.' + this.options.targets.nextButton).toggleClass('inactive', true); 6336 } 6337 // what's last year looking like? 6338 if(start && moment(start).subtract('years', 1).isBefore(moment(this.month).subtract('years', 1)) ) { 6339 this.element.find('.' + this.options.targets.previousYearButton).toggleClass('inactive', true); 6340 } 6341 // how about next year? 6342 if(end && moment(end).add('years', 1).isAfter(moment(this.month).add('years', 1)) ) { 6343 this.element.find('.' + this.options.targets.nextYearButton).toggleClass('inactive', true); 6344 } 6345 // today? we could put this in init(), but we want to support the user changing the constraints on a living instance. 6346 if(( start && start.isAfter( moment(), 'month' ) ) || ( end && end.isBefore( moment(), 'month' ) )) { 6347 this.element.find('.' + this.options.targets.today).toggleClass('inactive', true); 6348 } 6349 } 6350 6351 6352 if(this.options.doneRendering) { 6353 this.options.doneRendering.apply(this, []); 6354 } 6355 }; 6356 6357 Clndr.prototype.bindEvents = function() { 6358 var $container = $(this.element); 6359 var self = this; 6360 6361 // target the day elements and give them click events 6362 $container.on('click', '.'+this.options.targets.day, function(event) { 6363 if(self.options.clickEvents.click) { 6364 var target = self.buildTargetObject(event.currentTarget, true); 6365 self.options.clickEvents.click.apply(self, [target]); 6366 } 6367 // if adjacentDaysChangeMonth is on, we need to change the month here. 6368 if(self.options.adjacentDaysChangeMonth) { 6369 if($(event.currentTarget).is(".last-month")) { 6370 self.backActionWithContext(self); 6371 } else if($(event.currentTarget).is(".next-month")) { 6372 self.forwardActionWithContext(self); 6373 } 6374 } 6375 }); 6376 // target the empty calendar boxes as well 6377 $container.on('click', '.'+this.options.targets.empty, function(event) { 6378 if(self.options.clickEvents.click) { 6379 var target = self.buildTargetObject(event.currentTarget, false); 6380 self.options.clickEvents.click.apply(self, [target]); 6381 } 6382 if(self.options.adjacentDaysChangeMonth) { 6383 if($(event.currentTarget).is(".last-month")) { 6384 self.backActionWithContext(self); 6385 } else if($(event.currentTarget).is(".next-month")) { 6386 self.forwardActionWithContext(self); 6387 } 6388 } 6389 });
6390 6391 // bind the previous, next and today buttons 6392 $container 6393 .on('click', '.'+this.options.targets.previousButton, { context: this }, this.backAction) 6394 .on('click', '.'+this.options.targets.nextButton, { context: this }, this.forwardAction) 6395 .on('click', '.'+this.options.targets.todayButton, { context: this }, this.todayAction) 6396 .on('click', '.'+this.options.targets.nextYearButton, { context: this }, this.nextYearAction) 6397 .on('click', '.'+this.options.targets.previousYearButton, { context: this }, this.previousYearAction); 6398 } 6399 6400 // If the user provided a click callback we'd like to give them something nice to work with. 6401 // buildTargetObject takes the DOM element that was clicked and returns an object with 6402 // the DOM element, events, and the date (if the latter two exist). Currently it is based on the id, 6403 // however it'd be nice to use a data- attribute in the future. 6404 Clndr.prototype.buildTargetObject = function(currentTarget, targetWasDay) { 6405 // This is our default target object, assuming we hit an empty day with no events. 6406 var target = { 6407 element: currentTarget, 6408 events: [], 6409 date: null 6410 }; 6411 // did we click on a day or just an empty box? 6412 if(targetWasDay) { 6413 var dateString; 6414 6415 // Our identifier is in the list of classNames. Find it! 6416 var classNameIndex = currentTarget.className.indexOf('calendar-day-'); 6417 if(classNameIndex !== 0) { 6418 // our unique identifier is always 23 characters long. 6419 // If this feels a little wonky, that's probably because it is. 6420 // Open to suggestions on how to improve this guy. 6421 dateString = currentTarget.className.substring(classNameIndex + 13, classNameIndex + 23); 6422 target.date = moment(dateString); 6423 } else { 6424 target.date = null; 6425 } 6426 6427 // do we have events? 6428 if(this.options.events) { 6429 // are any of the events happening today? 6430 if(this.options.multiDayEvents) { 6431 target.events = $.makeArray( $(this.options.events).filter( function() { 6432 // filter the dates down to the ones that match. 6433 return ( ( target.date.isSame(this._clndrStartDateObject, 'day') || target.date.isAfter(this._clndrStartDateObject, 'day') ) && 6434 ( target.date.isSame(this._clndrEndDateObject, 'day') || target.date.isBefore(this._clndrEndDateObject, 'day') ) ); 6435 }) ); 6436 } else { 6437 target.events = $.makeArray( $(this.options.events).filter( function() { 6438 // filter the dates down to the ones that match. 6439 return this._clndrDateObject.format('YYYY-MM-DD') == dateString; 6440 }) ); 6441 } 6442 } 6443 } 6444 6445 return target; 6446 } 6447 6448 // the click handlers in bindEvents need a context, so these are wrappers 6449 // to the actual functions. Todo: better way to handle this? 6450 Clndr.prototype.forwardAction = function(event) { 6451 var self = event.data.context; 6452 self.forwardActionWithContext(self); 6453 }; 6454 6455 Clndr.prototype.backAction = function(event) { 6456 var self = event.data.context; 6457 self.backActionWithContext(self); 6458 }; 6459 6460 // These are called directly, except for in the bindEvent click handlers, 6461 // where forwardAction and backAction proxy to these guys. 6462 Clndr.prototype.backActionWithContext = function(self) { 6463 // before we do anything, check if there is an inactive class on the month control. 6464 // if it does, we want to return and take no action. 6465 if(self.element.find('.' + self.options.targets.previousButton).hasClass('inactive')) { 6466 return; 6467 } 6468 6469 // is subtracting one month going to switch the year? 6470 var yearChanged = !self.month.isSame( moment(self.month).subtract('months', 1), 'year'); 6471 self.month.subtract('months', 1); 6472 6473 self.render(); 6474 6475 if(self.options.clickEvents.previousMonth) { 6476 self.options.clickEvents.previousMonth.apply( self, [moment(self.month)] ); 6477 } 6478 if(self.options.clickEvents.onMonthChange) { 6479 self.options.clickEvents.onMonthChange.apply( self, [moment(self.month)] ); 6480 } 6481 if(yearChanged) { 6482 if(self.options.clickEvents.onYearChange) { 6483 self.options.clickEvents.onYearChange.apply( self, [moment(self.month)] ); 6484 } 6485 } 6486 }; 6487 6488 Clndr.prototype.forwardActionWithContext = function(self) { 6489 // before we do anything, check if there is an inactive class on the month control. 6490 // if it does, we want to return and take no action. 6491 if(self.element.find('.' + self.options.targets.nextButton).hasClass('inactive')) { 6492 return; 6493 } 6494 6495 // is adding one month going to switch the year? 6496 var yearChanged = !self.month.isSame( moment(self.month).add('months', 1), 'year'); 6497 self.month.add('months', 1); 6498 6499 self.render(); 6500 6501 if(self.options.clickEvents.nextMonth) { 6502 self.options.clickEvents.nextMonth.apply(self, [moment(self.month)]); 6503 } 6504 if(self.options.clickEvents.onMonthChange) { 6505 self.options.clickEvents.onMonthChange.apply(self, [moment(self.month)]); 6506 } 6507 if(yearChanged) { 6508 if(self.options.clickEvents.onYearChange) { 6509 self.options.clickEvents.onYearChange.apply( self, [moment(self.month)] ); 6510 } 6511 } 6512 }; 6513 6514 Clndr.prototype.todayAction = function(event) { 6515 var self = event.data.context; 6516 6517 // did we switch months when the today button was hit? 6518 var monthChanged = !self.month.isSame(moment(), 'month'); 6519 var yearChanged = !self.month.isSame(moment(), 'year'); 6520 6521 self.month = moment().startOf('month'); 6522 6523 // fire the today event handler regardless of whether the month changed. 6524 if(self.options.clickEvents.today) { 6525 self.options.clickEvents.today.apply( self, [moment(self.month)] ); 6526 } 6527
6528 if(monthChanged) { 6529 // no need to re-render if we didn't change months. 6530 self.render(); 6531 6532 self.month = moment(); 6533 // fire the onMonthChange callback 6534 if(self.options.clickEvents.onMonthChange) { 6535 self.options.clickEvents.onMonthChange.apply( self, [moment(self.month)] ); 6536 } 6537 // maybe fire the onYearChange callback? 6538 if(yearChanged) { 6539 if(self.options.clickEvents.onYearChange) { 6540 self.options.clickEvents.onYearChange.apply( self, [moment(self.month)] ); 6541 } 6542 } 6543 } 6544 }; 6545 6546 Clndr.prototype.nextYearAction = function(event) { 6547 var self = event.data.context; 6548 // before we do anything, check if there is an inactive class on the month control. 6549 // if it does, we want to return and take no action. 6550 if(self.element.find('.' + self.options.targets.nextYearButton).hasClass('inactive')) { 6551 return; 6552 } 6553 6554 self.month.add('years', 1); 6555 self.render(); 6556 6557 if(self.options.clickEvents.nextYear) { 6558 self.options.clickEvents.nextYear.apply( self, [moment(self.month)] ); 6559 } 6560 if(self.options.clickEvents.onMonthChange) { 6561 self.options.clickEvents.onMonthChange.apply( self, [moment(self.month)] ); 6562 } 6563 if(self.options.clickEvents.onYearChange) { 6564 self.options.clickEvents.onYearChange.apply( self, [moment(self.month)] ); 6565 } 6566 }; 6567 6568 Clndr.prototype.previousYearAction = function(event) { 6569 var self = event.data.context; 6570 // before we do anything, check if there is an inactive class on the month control. 6571 // if it does, we want to return and take no action. 6572 if(self.element.find('.' + self.options.targets.previousYear).hasClass('inactive')) { 6573 return; 6574 } 6575 6576 self.month.subtract('years', 1); 6577 self.render(); 6578 6579 if(self.options.clickEvents.previousYear) { 6580 self.options.clickEvents.previousYear.apply( self, [moment(self.month)] ); 6581 } 6582 if(self.options.clickEvents.onMonthChange) { 6583 self.options.clickEvents.onMonthChange.apply( self, [moment(self.month)] ); 6584 } 6585 if(self.options.clickEvents.onYearChange) { 6586 self.options.clickEvents.onYearChange.apply( self, [moment(self.month)] ); 6587 } 6588 }; 6589 6590 Clndr.prototype.forward = function(options) { 6591 this.month.add('months', 1); 6592 this.render(); 6593 if(options && options.withCallbacks) { 6594 if(this.options.clickEvents.onMonthChange) { 6595 this.options.clickEvents.onMonthChange.apply( this, [moment(this.month)] ); 6596 } 6597 6598 // We entered a new year 6599 if (this.month.month() === 0 && this.options.clickEvents.onYearChange) { 6600 this.options.clickEvents.onYearChange.apply( this, [moment(this.month)] ); 6601 } 6602 } 6603 6604 return this; 6605 } 6606 6607 Clndr.prototype.back = function(options) { 6608 this.month.subtract('months', 1); 6609 this.render(); 6610 if(options && options.withCallbacks) { 6611 if(this.options.clickEvents.onMonthChange) { 6612 this.options.clickEvents.onMonthChange.apply( this, [moment(this.month)] ); 6613 } 6614 6615 // We went all the way back to previous year 6616 if (this.month.month() === 11 && this.options.clickEvents.onYearChange) { 6617 this.options.clickEvents.onYearChange.apply( this, [moment(this.month)] ); 6618 } 6619 } 6620 6621 return this; 6622 } 6623 6624 // alternate names for convenience 6625 Clndr.prototype.next = function(options) { 6626 this.forward(options); 6627 return this; 6628 } 6629 6630 Clndr.prototype.previous = function(options) { 6631 this.back(options); 6632 return this; 6633 } 6634 6635 Clndr.prototype.setMonth = function(newMonth, options) { 6636 // accepts 0 - 11 or a full/partial month name e.g. "Jan", "February", "Mar" 6637 this.month.month(newMonth); 6638 this.render(); 6639 if(options && options.withCallbacks) { 6640 if(this.options.clickEvents.onMonthChange) { 6641 this.options.clickEvents.onMonthChange.apply( this, [moment(this.month)] ); 6642 } 6643 } 6644 return this; 6645 } 6646 6647 Clndr.prototype.nextYear = function(options) { 6648 this.month.add('year', 1); 6649 this.render(); 6650 if(options && options.withCallbacks) { 6651 if(this.options.clickEvents.onYearChange) { 6652 this.options.clickEvents.onYearChange.apply( this, [moment(this.month)] ); 6653 } 6654 } 6655 return this; 6656 } 6657 6658 Clndr.prototype.previousYear = function(options) { 6659 this.month.subtract('year', 1); 6660 this.render(); 6661 if(options && options.withCallbacks) { 6662 if(this.options.clickEvents.onYearChange) { 6663 this.options.clickEvents.onYearChange.apply( this, [moment(this.month)] ); 6664 } 6665 } 6666 return this; 6667 } 6668 6669 Clndr.prototype.setYear = function(newYear, options) { 6670 this.month.year(newYear); 6671 this.render(); 6672 if(options && options.withCallbacks) { 6673 if(this.options.clickEvents.onYearChange) { 6674 this.options.clickEvents.onYearChange.apply( this, [moment(this.month)] ); 6675 } 6676 } 6677 return this; 6678 } 6679 6680 Clndr.prototype.setEvents = function(events) { 6681 // go through each event and add a moment object 6682 if(this.options.multiDayEvents) { 6683 this.options.events = this.addMultiDayMomentObjectsToEvents(events); 6684 } else { 6685 this.options.events = this.addMomentObjectToEvents(events); 6686 } 6687 6688 this.render(); 6689 return this; 6690 }; 6691 6692 Clndr.prototype.addEvents = function(events) { 6693 // go through each event and add a moment object 6694 if(this.options.multiDayEvents) { 6695 this.options.events = $.merge(this.options.events, this.addMultiDayMomentObjectsToEvents(events)); 6696 } else { 6697 this.options.events = $.merge(this.options.events, this.addMomentObjectToEvents(events)); 6698 } 6699 6700 this.render(); 6701 return this; 6702 }; 6703 6704 Clndr.prototype.addMomentObjectToEvents = function(events) { 6705 var self = this; 6706 var i = 0, l = events.length; 6707 for(i; i < l; i++) { 6708 // stuff a _clndrDateObject in each event, which really, REALLY should not be 6709 // overriding any existing object... Man that would be weird. 6710 events[i]._clndrDateObject = moment( events[i][self.options.dateParameter] ); 6711 } 6712 return events; 6713 } 6714 6715 Clndr.prototype.addMultiDayMomentObjectsToEvents = function(events) { 6716 var self = this; 6717 var i = 0, l = events.length; 6718 for(i; i < l; i++) { 6719 events[i]._clndrStartDateObject = moment( events[i][self.options.multiDayEvents.startDate] ); 6720 events[i]._clndrEndDateObject = moment( events[i][self.options.multiDayEvents.endDate] ); 6721 } 6722 return events; 6723 } 6724 6725 Clndr.prototype.calendarDay = function(options) { 6726 var defaults = { day: "", classes: this.options.targets.empty, events: [], date: null }; 6727 return $.extend({}, defaults, options); 6728 } 6729 6730 $.fn.clndr = function(options) { 6731 if(this.length === 1) { 6732 if(!this.data('plugin_clndr')) { 6733 var clndr_instance = new Clndr(this, options); 6734 this.data('plugin_clndr', clndr_instance); 6735 return clndr_instance; 6736 } 6737 } else if(this.length > 1) { 6738 throw new Error("CLNDR does not support multiple elements yet. Make sure your clndr selector returns only one element."); 6739 } 6740 } 6741 6742})( jQuery, window, document ); 6743 6744 6745; 6746////pf: javascript/mustache.js 6747/*! 6748 * mustache.js - Logic-less {{mustache}} templates with JavaScript 6749 * http://github.com/janl/mustache.js 6750 */ 6751 6752/*global define: false*/ 6753 6754(function (global, factory) {
6755 if (typeof exports === "object" && exports) { 6756 factory(exports); // CommonJS 6757 } else if (typeof define === "function" && define.amd) { 6758 define(factory({})); // AMD 6759 } else { 6760 global.Mustache = factory({}); // <script> 6761 } 6762}(this, function (mustache) { 6763 6764 var Object_toString = Object.prototype.toString; 6765 var isArray = Array.isArray || function (object) { 6766 return Object_toString.call(object) === '[object Array]'; 6767 }; 6768 6769 function isFunction(object) { 6770 return typeof object === 'function'; 6771 } 6772 6773 function escapeRegExp(string) { 6774 return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); 6775 } 6776 6777 // Workaround for https://issues.apache.org/jira/browse/COUCHDB-577 6778 // See https://github.com/janl/mustache.js/issues/189 6779 var RegExp_test = RegExp.prototype.test; 6780 function testRegExp(re, string) { 6781 return RegExp_test.call(re, string); 6782 } 6783 6784 var nonSpaceRe = /\S/; 6785 function isWhitespace(string) { 6786 return !testRegExp(nonSpaceRe, string); 6787 } 6788 6789 var entityMap = { 6790 "&": "&", 6791 "<": "<", 6792 ">": ">", 6793 '"': '"', 6794 "'": ''', 6795 "/": '/' 6796 }; 6797 6798 function escapeHtml(string) { 6799 return String(string).replace(/[&<>"'\/]/g, function (s) { 6800 return entityMap[s]; 6801 }); 6802 } 6803 6804 var whiteRe = /\s*/; 6805 var spaceRe = /\s+/; 6806 var equalsRe = /\s*=/; 6807 var curlyRe = /\s*\}/; 6808 var tagRe = /#|\^|\/|>|\{|&|=|!/; 6809 6810 /** 6811 * Breaks up the given `template` string into a tree of tokens. If the `tags` 6812 * argument is given here it must be an array with two string values: the 6813 * opening and closing tags used in the template (e.g. [ "<%", "%>" ]). Of 6814 * course, the default is to use mustaches (i.e. mustache.tags). 6815 * 6816 * A token is an array with at least 4 elements. The first element is the 6817 * mustache symbol that was used inside the tag, e.g. "#" or "&". If the tag 6818 * did not contain a symbol (i.e. {{myValue}}) this element is "name". For 6819 * all text that appears outside a symbol this element is "text". 6820 * 6821 * The second element of a token is its "value". For mustache tags this is 6822 * whatever else was inside the tag besides the opening symbol. For text tokens 6823 * this is the text itself. 6824 * 6825 * The third and fourth elements of the token are the start and end indices, 6826 * respectively, of the token in the original template. 6827 * 6828 * Tokens that are the root node of a subtree contain two more elements: 1) an 6829 * array of tokens in the subtree and 2) the index in the original template at 6830 * which the closing tag for that section begins. 6831 */ 6832 function parseTemplate(template, tags) { 6833 if (!template) 6834 return []; 6835 6836 var sections = []; // Stack to hold section tokens 6837 var tokens = []; // Buffer to hold the tokens 6838 var spaces = []; // Indices of whitespace tokens on the current line 6839 var hasTag = false; // Is there a {{tag}} on the current line? 6840 var nonSpace = false; // Is there a non-space char on the current line? 6841 6842 // Strips all whitespace tokens array for the current line 6843 // if there was a {{#tag}} on it and otherwise only space. 6844 function stripSpace() { 6845 if (hasTag && !nonSpace) { 6846 while (spaces.length) 6847 delete tokens[spaces.pop()]; 6848 } else { 6849 spaces = []; 6850 } 6851 6852 hasTag = false; 6853 nonSpace = false; 6854 } 6855 6856 var openingTagRe, closingTagRe, closingCurlyRe; 6857 function compileTags(tags) { 6858 if (typeof tags === 'string') 6859 tags = tags.split(spaceRe, 2); 6860 6861 if (!isArray(tags) || tags.length !== 2) 6862 throw new Error('Invalid tags: ' + tags); 6863 6864 openingTagRe = new RegExp(escapeRegExp(tags[0]) + '\\s*'); 6865 closingTagRe = new RegExp('\\s*' + escapeRegExp(tags[1])); 6866 closingCurlyRe = new RegExp('\\s*' + escapeRegExp('}' + tags[1])); 6867 } 6868 6869 compileTags(tags || mustache.tags); 6870 6871 var scanner = new Scanner(template); 6872 6873 var start, type, value, chr, token, openSection; 6874 while (!scanner.eos()) { 6875 start = scanner.pos; 6876 6877 // Match any text between tags. 6878 value = scanner.scanUntil(openingTagRe); 6879 6880 if (value) { 6881 for (var i = 0, valueLength = value.length; i < valueLength; ++i) { 6882 chr = value.charAt(i); 6883 6884 if (isWhitespace(chr)) {
vendor: 7,266 bytes, lines 6885-7160
6885 spaces.push(tokens.length); 6886 } else { 6887 nonSpace = true; 6888 } 6889 6890 tokens.push([ 'text', chr, start, start + 1 ]); 6891 start += 1; 6892 6893 // Check for whitespace on the current line. 6894 if (chr === '\n') 6895 stripSpace(); 6896 } 6897 } 6898 6899 // Match the opening tag. 6900 if (!scanner.scan(openingTagRe)) 6901 break; 6902 6903 hasTag = true; 6904 6905 // Get the tag type. 6906 type = scanner.scan(tagRe) || 'name'; 6907 scanner.scan(whiteRe); 6908 6909 // Get the tag value. 6910 if (type === '=') { 6911 value = scanner.scanUntil(equalsRe); 6912 scanner.scan(equalsRe); 6913 scanner.scanUntil(closingTagRe); 6914 } else if (type === '{') { 6915 value = scanner.scanUntil(closingCurlyRe); 6916 scanner.scan(curlyRe); 6917 scanner.scanUntil(closingTagRe); 6918 type = '&'; 6919 } else { 6920 value = scanner.scanUntil(closingTagRe); 6921 } 6922 6923 // Match the closing tag. 6924 if (!scanner.scan(closingTagRe)) 6925 throw new Error('Unclosed tag at ' + scanner.pos); 6926 6927 token = [ type, value, start, scanner.pos ]; 6928 tokens.push(token); 6929 6930 if (type === '#' || type === '^') { 6931 sections.push(token); 6932 } else if (type === '/') { 6933 // Check section nesting. 6934 openSection = sections.pop(); 6935 6936 if (!openSection) 6937 throw new Error('Unopened section "' + value + '" at ' + start); 6938 6939 if (openSection[1] !== value) 6940 throw new Error('Unclosed section "' + openSection[1] + '" at ' + start); 6941 } else if (type === 'name' || type === '{' || type === '&') { 6942 nonSpace = true; 6943 } else if (type === '=') { 6944 // Set the tags for the next time around. 6945 compileTags(value); 6946 } 6947 } 6948 6949 // Make sure there are no open sections when we're done. 6950 openSection = sections.pop(); 6951 6952 if (openSection) 6953 throw new Error('Unclosed section "' + openSection[1] + '" at ' + scanner.pos); 6954 6955 return nestTokens(squashTokens(tokens)); 6956 } 6957 6958 /** 6959 * Combines the values of consecutive text tokens in the given `tokens` array 6960 * to a single token. 6961 */ 6962 function squashTokens(tokens) { 6963 var squashedTokens = []; 6964 6965 var token, lastToken; 6966 for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) { 6967 token = tokens[i]; 6968 6969 if (token) { 6970 if (token[0] === 'text' && lastToken && lastToken[0] === 'text') { 6971 lastToken[1] += token[1]; 6972 lastToken[3] = token[3]; 6973 } else { 6974 squashedTokens.push(token); 6975 lastToken = token; 6976 } 6977 } 6978 } 6979 6980 return squashedTokens; 6981 } 6982 6983 /** 6984 * Forms the given array of `tokens` into a nested tree structure where 6985 * tokens that represent a section have two additional items: 1) an array of 6986 * all tokens that appear in that section and 2) the index in the original 6987 * template that represents the end of that section. 6988 */ 6989 function nestTokens(tokens) { 6990 var nestedTokens = []; 6991 var collector = nestedTokens; 6992 var sections = []; 6993 6994 var token, section; 6995 for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) { 6996 token = tokens[i]; 6997 6998 switch (token[0]) { 6999 case '#': 7000 case '^': 7001 collector.push(token); 7002 sections.push(token); 7003 collector = token[4] = []; 7004 break; 7005 case '/': 7006 section = sections.pop(); 7007 section[5] = token[2]; 7008 collector = sections.length > 0 ? sections[sections.length - 1][4] : nestedTokens; 7009 break; 7010 default: 7011 collector.push(token); 7012 } 7013 } 7014 7015 return nestedTokens; 7016 } 7017 7018 /** 7019 * A simple string scanner that is used by the template parser to find 7020 * tokens in template strings. 7021 */ 7022 function Scanner(string) { 7023 this.string = string; 7024 this.tail = string; 7025 this.pos = 0; 7026 } 7027 7028 /** 7029 * Returns `true` if the tail is empty (end of string). 7030 */ 7031 Scanner.prototype.eos = function () { 7032 return this.tail === ""; 7033 }; 7034 7035 /** 7036 * Tries to match the given regular expression at the current position. 7037 * Returns the matched text if it can match, the empty string otherwise. 7038 */ 7039 Scanner.prototype.scan = function (re) { 7040 var match = this.tail.match(re); 7041 7042 if (!match || match.index !== 0) 7043 return ''; 7044 7045 var string = match[0]; 7046 7047 this.tail = this.tail.substring(string.length); 7048 this.pos += string.length; 7049 7050 return string; 7051 }; 7052 7053 /** 7054 * Skips all text until the given regular expression can be matched. Returns 7055 * the skipped string, which is the entire tail if no match can be made. 7056 */ 7057 Scanner.prototype.scanUntil = function (re) { 7058 var index = this.tail.search(re), match; 7059 7060 switch (index) { 7061 case -1: 7062 match = this.tail; 7063 this.tail = ""; 7064 break; 7065 case 0: 7066 match = ""; 7067 break; 7068 default: 7069 match = this.tail.substring(0, index); 7070 this.tail = this.tail.substring(index); 7071 } 7072 7073 this.pos += match.length; 7074 7075 return match; 7076 }; 7077 7078 /** 7079 * Represents a rendering context by wrapping a view object and 7080 * maintaining a reference to the parent context. 7081 */ 7082 function Context(view, parentContext) { 7083 this.view = view == null ? {} : view; 7084 this.cache = { '.': this.view }; 7085 this.parent = parentContext; 7086 } 7087 7088 /** 7089 * Creates a new context using the given view with this context 7090 * as the parent. 7091 */ 7092 Context.prototype.push = function (view) { 7093 return new Context(view, this); 7094 }; 7095 7096 /** 7097 * Returns the value of the given name in this context, traversing 7098 * up the context hierarchy if the value is absent in this context's view. 7099 */ 7100 Context.prototype.lookup = function (name) { 7101 var cache = this.cache; 7102 7103 var value; 7104 if (name in cache) { 7105 value = cache[name]; 7106 } else { 7107 var context = this, names, index; 7108 7109 while (context) { 7110 if (name.indexOf('.') > 0) { 7111 value = context.view; 7112 names = name.split('.'); 7113 index = 0; 7114 7115 while (value != null && index < names.length) 7116 value = value[names[index++]]; 7117 } else { 7118 value = context.view[name]; 7119 } 7120 7121 if (value != null) 7122 break; 7123 7124 context = context.parent; 7125 } 7126 7127 cache[name] = value; 7128 } 7129 7130 if (isFunction(value)) 7131 value = value.call(this.view); 7132 7133 return value; 7134 }; 7135 7136 /** 7137 * A Writer knows how to take a stream of tokens and render them to a 7138 * string, given a context. It also maintains a cache of templates to 7139 * avoid the need to parse the same template twice. 7140 */ 7141 function Writer() { 7142 this.cache = {}; 7143 } 7144 7145 /** 7146 * Clears all cached templates in this writer. 7147 */ 7148 Writer.prototype.clearCache = function () { 7149 this.cache = {}; 7150 }; 7151 7152 /** 7153 * Parses and caches the given `template` and returns the array of tokens 7154 * that is generated from the parse. 7155 */ 7156 Writer.prototype.parse = function (template, tags) { 7157 var cache = this.cache; 7158 var tokens = cache[template]; 7159 7160 if (tokens == null)
7161 tokens = cache[template] = parseTemplate(template, tags); 7162 7163 return tokens; 7164 }; 7165 7166 /** 7167 * High-level method that is used to render the given `template` with 7168 * the given `view`. 7169 * 7170 * The optional `partials` argument may be an object that contains the 7171 * names and templates of partials that are used in the template. It may 7172 * also be a function that is used to load partial templates on the fly 7173 * that takes a single argument: the name of the partial. 7174 */ 7175 Writer.prototype.render = function (template, view, partials) { 7176 var tokens = this.parse(template); 7177 var context = (view instanceof Context) ? view : new Context(view); 7178 return this.renderTokens(tokens, context, partials, template); 7179 }; 7180 7181 /** 7182 * Low-level method that renders the given array of `tokens` using 7183 * the given `context` and `partials`. 7184 * 7185 * Note: The `originalTemplate` is only ever used to extract the portion 7186 * of the original template that was contained in a higher-order section. 7187 * If the template doesn't use higher-order sections, this argument may 7188 * be omitted. 7189 */ 7190 Writer.prototype.renderTokens = function (tokens, context, partials, originalTemplate) { 7191 var buffer = ''; 7192 7193 // This function is used to render an arbitrary template 7194 // in the current context by higher-order sections. 7195 var self = this; 7196 function subRender(template) { 7197 return self.render(template, context, partials); 7198 } 7199 7200 var token, value; 7201 for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) { 7202 token = tokens[i]; 7203 7204 switch (token[0]) { 7205 case '#': 7206 value = context.lookup(token[1]); 7207 7208 if (!value) 7209 continue; 7210 7211 if (isArray(value)) { 7212 for (var j = 0, valueLength = value.length; j < valueLength; ++j) { 7213 buffer += this.renderTokens(token[4], context.push(value[j]), partials, originalTemplate); 7214 } 7215 } else if (typeof value === 'object' || typeof value === 'string') { 7216 buffer += this.renderTokens(token[4], context.push(value), partials, originalTemplate); 7217 } else if (isFunction(value)) { 7218 if (typeof originalTemplate !== 'string') 7219 throw new Error('Cannot use higher-order sections without the original template'); 7220 7221 // Extract the portion of the original template that the section contains. 7222 value = value.call(context.view, originalTemplate.slice(token[3], token[5]), subRender); 7223 7224 if (value != null) 7225 buffer += value; 7226 } else { 7227 buffer += this.renderTokens(token[4], context, partials, originalTemplate); 7228 } 7229 7230 break; 7231 case '^': 7232 value = context.lookup(token[1]); 7233 7234 // Use JavaScript's definition of falsy. Include empty arrays. 7235 // See https://github.com/janl/mustache.js/issues/186 7236 if (!value || (isArray(value) && value.length === 0)) 7237 buffer += this.renderTokens(token[4], context, partials, originalTemplate); 7238 7239 break; 7240 case '>': 7241 if (!partials) 7242 continue; 7243 7244 value = isFunction(partials) ? partials(token[1]) : partials[token[1]]; 7245 7246 if (value != null) 7247 buffer += this.renderTokens(this.parse(value), context, partials, value); 7248 7249 break; 7250 case '&': 7251 value = context.lookup(token[1]); 7252 7253 if (value != null) 7254 buffer += value; 7255 7256 break; 7257 case 'name': 7258 value = context.lookup(token[1]); 7259 7260 if (value != null) 7261 buffer += mustache.escape(value); 7262 7263 break; 7264 case 'text': 7265 buffer += token[1]; 7266 break; 7267 } 7268 } 7269 7270 return buffer; 7271 }; 7272 7273 mustache.name = "mustache.js"; 7274 mustache.version = "0.8.1"; 7275 mustache.tags = [ "{{", "}}" ]; 7276 7277 // All high-level mustache.* functions use this writer. 7278 var defaultWriter = new Writer(); 7279 7280 /** 7281 * Clears all cached templates in the default writer. 7282 */ 7283 mustache.clearCache = function () { 7284 return defaultWriter.clearCache(); 7285 }; 7286 7287 /** 7288 * Parses and caches the given template in the default writer and returns the 7289 * array of tokens it contains. Doing this ahead of time avoids the need to 7290 * parse templates on the fly as they are rendered. 7291 */ 7292 mustache.parse = function (template, tags) { 7293 return defaultWriter.parse(template, tags); 7294 }; 7295 7296 /** 7297 * Renders the `template` with the given `view` and `partials` using the 7298 * default writer. 7299 */ 7300 mustache.render = function (template, view, partials) { 7301 return defaultWriter.render(template, view, partials); 7302 }; 7303 7304 // This is here for backwards compatibility with 0.4.x. 7305 mustache.to_html = function (template, view, partials, send) { 7306 var result = mustache.render(template, view, partials); 7307 7308 if (isFunction(send)) { 7309 send(result); 7310 } else { 7311 return result; 7312 } 7313 }; 7314 7315 // Export the escaping function so that the user may override it. 7316 // See https://github.com/janl/mustache.js/issues/244 7317 mustache.escape = escapeHtml; 7318 7319 // Export these mainly for testing, but also for advanced usage. 7320 mustache.Scanner = Scanner; 7321 mustache.Context = Context; 7322 mustache.Writer = Writer; 7323 7324 return mustache; 7325 7326})); 7327 7328 7329; 7330////pf: javascript/moment.js 7331//! moment.js 7332 7333; (function (global, factory) { 7334 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 7335 typeof define === 'function' && define.amd ? define(factory) : 7336 global.moment = factory() 7337}(this, (function () { 7338 'use strict'; 7339 7340 var hookCallback; 7341 7342 function hooks() { 7343 return hookCallback.apply(null, arguments); 7344 } 7345 7346 // This is done to register the method called with moment() 7347 // without creating circular dependencies. 7348 function setHookCallback(callback) { 7349 hookCallback = callback; 7350 } 7351 7352 function isArray(input) { 7353 return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]'; 7354 } 7355 7356 function isObject(input) { 7357 // IE8 will treat undefined and null as object if it wasn't for 7358 // input != null 7359 return input != null && Object.prototype.toString.call(input) === '[object Object]'; 7360 } 7361 7362 function isObjectEmpty(obj) { 7363 if (Object.getOwnPropertyNames) { 7364 return (Object.getOwnPropertyNames(obj).length === 0); 7365 } else { 7366 var k; 7367 for (k in obj) { 7368 if (obj.hasOwnProperty(k)) { 7369 return false; 7370 } 7371 } 7372 return true; 7373 } 7374 } 7375 7376 function isUndefined(input) { 7377 return input === void 0; 7378 } 7379 7380 function isNumber(input) { 7381 return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]'; 7382 } 7383 7384 function isDate(input) {
vendor: 35,563 bytes, lines 7385-8497
7385 return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]'; 7386 } 7387 7388 function map(arr, fn) { 7389 var res = [], i; 7390 for (i = 0; i < arr.length; ++i) { 7391 res.push(fn(arr[i], i)); 7392 } 7393 return res; 7394 } 7395 7396 function hasOwnProp(a, b) { 7397 return Object.prototype.hasOwnProperty.call(a, b); 7398 } 7399 7400 function extend(a, b) { 7401 for (var i in b) { 7402 if (hasOwnProp(b, i)) { 7403 a[i] = b[i]; 7404 } 7405 } 7406 7407 if (hasOwnProp(b, 'toString')) { 7408 a.toString = b.toString; 7409 } 7410 7411 if (hasOwnProp(b, 'valueOf')) { 7412 a.valueOf = b.valueOf; 7413 } 7414 7415 return a; 7416 } 7417 7418 function createUTC(input, format, locale, strict) { 7419 return createLocalOrUTC(input, format, locale, strict, true).utc(); 7420 } 7421 7422 function defaultParsingFlags() { 7423 // We need to deep clone this object. 7424 return { 7425 empty: false, 7426 unusedTokens: [], 7427 unusedInput: [], 7428 overflow: -2, 7429 charsLeftOver: 0, 7430 nullInput: false, 7431 invalidMonth: null, 7432 invalidFormat: false, 7433 userInvalidated: false, 7434 iso: false, 7435 parsedDateParts: [], 7436 meridiem: null, 7437 rfc2822: false, 7438 weekdayMismatch: false 7439 }; 7440 } 7441 7442 function getParsingFlags(m) { 7443 if (m._pf == null) { 7444 m._pf = defaultParsingFlags(); 7445 } 7446 return m._pf; 7447 } 7448 7449 var some; 7450 if (Array.prototype.some) { 7451 some = Array.prototype.some; 7452 } else { 7453 some = function (fun) { 7454 var t = Object(this); 7455 var len = t.length >>> 0; 7456 7457 for (var i = 0; i < len; i++) { 7458 if (i in t && fun.call(this, t[i], i, t)) { 7459 return true; 7460 } 7461 } 7462 7463 return false; 7464 }; 7465 } 7466 7467 function isValid(m) { 7468 if (m._isValid == null) { 7469 var flags = getParsingFlags(m); 7470 var parsedParts = some.call(flags.parsedDateParts, function (i) { 7471 return i != null; 7472 }); 7473 var isNowValid = !isNaN(m._d.getTime()) && 7474 flags.overflow < 0 && 7475 !flags.empty && 7476 !flags.invalidMonth && 7477 !flags.invalidWeekday && 7478 !flags.weekdayMismatch && 7479 !flags.nullInput && 7480 !flags.invalidFormat && 7481 !flags.userInvalidated && 7482 (!flags.meridiem || (flags.meridiem && parsedParts)); 7483 7484 if (m._strict) { 7485 isNowValid = isNowValid && 7486 flags.charsLeftOver === 0 && 7487 flags.unusedTokens.length === 0 && 7488 flags.bigHour === undefined; 7489 } 7490 7491 if (Object.isFrozen == null || !Object.isFrozen(m)) { 7492 m._isValid = isNowValid; 7493 } 7494 else { 7495 return isNowValid; 7496 } 7497 } 7498 return m._isValid; 7499 } 7500 7501 function createInvalid(flags) { 7502 var m = createUTC(NaN); 7503 if (flags != null) { 7504 extend(getParsingFlags(m), flags); 7505 } 7506 else { 7507 getParsingFlags(m).userInvalidated = true; 7508 } 7509 7510 return m; 7511 } 7512 7513 // Plugins that add properties should also add the key here (null value), 7514 // so we can properly clone ourselves. 7515 var momentProperties = hooks.momentProperties = []; 7516 7517 function copyConfig(to, from) { 7518 var i, prop, val; 7519 7520 if (!isUndefined(from._isAMomentObject)) { 7521 to._isAMomentObject = from._isAMomentObject; 7522 } 7523 if (!isUndefined(from._i)) { 7524 to._i = from._i; 7525 } 7526 if (!isUndefined(from._f)) { 7527 to._f = from._f; 7528 } 7529 if (!isUndefined(from._l)) { 7530 to._l = from._l; 7531 } 7532 if (!isUndefined(from._strict)) { 7533 to._strict = from._strict; 7534 } 7535 if (!isUndefined(from._tzm)) { 7536 to._tzm = from._tzm; 7537 } 7538 if (!isUndefined(from._isUTC)) { 7539 to._isUTC = from._isUTC; 7540 } 7541 if (!isUndefined(from._offset)) { 7542 to._offset = from._offset; 7543 } 7544 if (!isUndefined(from._pf)) { 7545 to._pf = getParsingFlags(from); 7546 } 7547 if (!isUndefined(from._locale)) { 7548 to._locale = from._locale; 7549 } 7550 7551 if (momentProperties.length > 0) { 7552 for (i = 0; i < momentProperties.length; i++) { 7553 prop = momentProperties[i]; 7554 val = from[prop]; 7555 if (!isUndefined(val)) { 7556 to[prop] = val; 7557 } 7558 } 7559 } 7560 7561 return to; 7562 } 7563 7564 var updateInProgress = false; 7565 7566 // Moment prototype object 7567 function Moment(config) { 7568 copyConfig(this, config); 7569 this._d = new Date(config._d != null ? config._d.getTime() : NaN); 7570 if (!this.isValid()) { 7571 this._d = new Date(NaN); 7572 } 7573 // Prevent infinite loop in case updateOffset creates new moment 7574 // objects. 7575 if (updateInProgress === false) { 7576 updateInProgress = true; 7577 hooks.updateOffset(this); 7578 updateInProgress = false; 7579 } 7580 } 7581 7582 function isMoment(obj) { 7583 return obj instanceof Moment || (obj != null && obj._isAMomentObject != null); 7584 } 7585 7586 function absFloor(number) { 7587 if (number < 0) { 7588 // -0 -> 0 7589 return Math.ceil(number) || 0; 7590 } else { 7591 return Math.floor(number); 7592 } 7593 } 7594 7595 function toInt(argumentForCoercion) { 7596 var coercedNumber = +argumentForCoercion, 7597 value = 0; 7598 7599 if (coercedNumber !== 0 && isFinite(coercedNumber)) { 7600 value = absFloor(coercedNumber); 7601 } 7602 7603 return value; 7604 } 7605 7606 // compare two arrays, return the number of differences 7607 function compareArrays(array1, array2, dontConvert) { 7608 var len = Math.min(array1.length, array2.length), 7609 lengthDiff = Math.abs(array1.length - array2.length), 7610 diffs = 0, 7611 i; 7612 for (i = 0; i < len; i++) { 7613 if ((dontConvert && array1[i] !== array2[i]) || 7614 (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) { 7615 diffs++; 7616 } 7617 } 7618 return diffs + lengthDiff; 7619 } 7620 7621 function warn(msg) { 7622 if (hooks.suppressDeprecationWarnings === false && 7623 (typeof console !== 'undefined') && console.warn) { 7624 console.warn('Deprecation warning: ' + msg); 7625 } 7626 } 7627 7628 function deprecate(msg, fn) { 7629 var firstTime = true; 7630 7631 return extend(function () { 7632 if (hooks.deprecationHandler != null) { 7633 hooks.deprecationHandler(null, msg); 7634 } 7635 if (firstTime) { 7636 var args = []; 7637 var arg; 7638 for (var i = 0; i < arguments.length; i++) { 7639 arg = ''; 7640 if (typeof arguments[i] === 'object') { 7641 arg += '\n[' + i + '] '; 7642 for (var key in arguments[0]) { 7643 arg += key + ': ' + arguments[0][key] + ', '; 7644 } 7645 arg = arg.slice(0, -2); // Remove trailing comma and space 7646 } else { 7647 arg = arguments[i]; 7648 } 7649 args.push(arg); 7650 } 7651 warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack); 7652 firstTime = false; 7653 } 7654 return fn.apply(this, arguments); 7655 }, fn); 7656 } 7657 7658 var deprecations = {}; 7659 7660 function deprecateSimple(name, msg) { 7661 if (hooks.deprecationHandler != null) { 7662 hooks.deprecationHandler(name, msg); 7663 } 7664 if (!deprecations[name]) { 7665 warn(msg); 7666 deprecations[name] = true; 7667 } 7668 } 7669 7670 hooks.suppressDeprecationWarnings = false; 7671 hooks.deprecationHandler = null; 7672 7673 function isFunction(input) { 7674 return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]'; 7675 } 7676 7677 function set(config) { 7678 var prop, i; 7679 for (i in config) { 7680 prop = config[i]; 7681 if (isFunction(prop)) { 7682 this[i] = prop; 7683 } else { 7684 this['_' + i] = prop; 7685 } 7686 } 7687 this._config = config; 7688 // Lenient ordinal parsing accepts just a number in addition to 7689 // number + (possibly) stuff coming from _dayOfMonthOrdinalParse. 7690 // TODO: Remove "ordinalParse" fallback in next major release. 7691 this._dayOfMonthOrdinalParseLenient = new RegExp( 7692 (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + 7693 '|' + (/\d{1,2}/).source); 7694 } 7695 7696 function mergeConfigs(parentConfig, childConfig) { 7697 var res = extend({}, parentConfig), prop; 7698 for (prop in childConfig) { 7699 if (hasOwnProp(childConfig, prop)) { 7700 if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) { 7701 res[prop] = {}; 7702 extend(res[prop], parentConfig[prop]); 7703 extend(res[prop], childConfig[prop]); 7704 } else if (childConfig[prop] != null) { 7705 res[prop] = childConfig[prop]; 7706 } else { 7707 delete res[prop]; 7708 } 7709 } 7710 } 7711 for (prop in parentConfig) { 7712 if (hasOwnProp(parentConfig, prop) && 7713 !hasOwnProp(childConfig, prop) && 7714 isObject(parentConfig[prop])) { 7715 // make sure changes to properties don't modify parent config 7716 res[prop] = extend({}, res[prop]); 7717 } 7718 } 7719 return res; 7720 } 7721 7722 function Locale(config) { 7723 if (config != null) { 7724 this.set(config); 7725 } 7726 } 7727 7728 var keys; 7729 7730 if (Object.keys) { 7731 keys = Object.keys; 7732 } else { 7733 keys = function (obj) { 7734 var i, res = []; 7735 for (i in obj) { 7736 if (hasOwnProp(obj, i)) { 7737 res.push(i); 7738 } 7739 } 7740 return res; 7741 }; 7742 } 7743 7744 var defaultCalendar = { 7745 sameDay: '[Today at] LT', 7746 nextDay: '[Tomorrow at] LT', 7747 nextWeek: 'dddd [at] LT', 7748 lastDay: '[Yesterday at] LT', 7749 lastWeek: '[Last] dddd [at] LT', 7750 sameElse: 'L' 7751 }; 7752 7753 function calendar(key, mom, now) { 7754 var output = this._calendar[key] || this._calendar['sameElse']; 7755 return isFunction(output) ? output.call(mom, now) : output; 7756 } 7757 7758 var defaultLongDateFormat = { 7759 LTS: 'h:mm:ss A', 7760 LT: 'h:mm A', 7761 L: 'MM/DD/YYYY', 7762 LL: 'MMMM D, YYYY', 7763 LLL: 'MMMM D, YYYY h:mm A', 7764 LLLL: 'dddd, MMMM D, YYYY h:mm A' 7765 }; 7766 7767 function longDateFormat(key) { 7768 var format = this._longDateFormat[key], 7769 formatUpper = this._longDateFormat[key.toUpperCase()]; 7770 7771 if (format || !formatUpper) { 7772 return format; 7773 } 7774 7775 this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) { 7776 return val.slice(1); 7777 }); 7778 7779 return this._longDateFormat[key]; 7780 } 7781 7782 var defaultInvalidDate = 'Invalid date'; 7783 7784 function invalidDate() { 7785 return this._invalidDate; 7786 } 7787 7788 var defaultOrdinal = '%d'; 7789 var defaultDayOfMonthOrdinalParse = /\d{1,2}/; 7790 7791 function ordinal(number) { 7792 return this._ordinal.replace('%d', number); 7793 } 7794 7795 var defaultRelativeTime = { 7796 future: 'in %s', 7797 past: '%s ago', 7798 s: 'a few seconds', 7799 ss: '%d seconds', 7800 m: 'a minute', 7801 mm: '%d minutes', 7802 h: 'an hour', 7803 hh: '%d hours', 7804 d: 'a day', 7805 dd: '%d days', 7806 M: 'a month', 7807 MM: '%d months', 7808 y: 'a year', 7809 yy: '%d years' 7810 }; 7811 7812 function relativeTime(number, withoutSuffix, string, isFuture) { 7813 var output = this._relativeTime[string]; 7814 return (isFunction(output)) ? 7815 output(number, withoutSuffix, string, isFuture) : 7816 output.replace(/%d/i, number); 7817 } 7818 7819 function pastFuture(diff, output) { 7820 var format = this._relativeTime[diff > 0 ? 'future' : 'past']; 7821 return isFunction(format) ? format(output) : format.replace(/%s/i, output); 7822 } 7823 7824 var aliases = {}; 7825 7826 function addUnitAlias(unit, shorthand) { 7827 var lowerCase = unit.toLowerCase(); 7828 aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit; 7829 } 7830 7831 function normalizeUnits(units) { 7832 return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined; 7833 } 7834 7835 function normalizeObjectUnits(inputObject) { 7836 var normalizedInput = {}, 7837 normalizedProp, 7838 prop; 7839 7840 for (prop in inputObject) { 7841 if (hasOwnProp(inputObject, prop)) { 7842 normalizedProp = normalizeUnits(prop); 7843 if (normalizedProp) { 7844 normalizedInput[normalizedProp] = inputObject[prop]; 7845 } 7846 } 7847 } 7848 7849 return normalizedInput; 7850 } 7851 7852 var priorities = {}; 7853 7854 function addUnitPriority(unit, priority) { 7855 priorities[unit] = priority; 7856 } 7857 7858 function getPrioritizedUnits(unitsObj) { 7859 var units = []; 7860 for (var u in unitsObj) { 7861 units.push({ unit: u, priority: priorities[u] }); 7862 } 7863 units.sort(function (a, b) { 7864 return a.priority - b.priority; 7865 }); 7866 return units; 7867 } 7868 7869 function zeroFill(number, targetLength, forceSign) { 7870 var absNumber = '' + Math.abs(number), 7871 zerosToFill = targetLength - absNumber.length, 7872 sign = number >= 0; 7873 return (sign ? (forceSign ? '+' : '') : '-') + 7874 Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber; 7875 } 7876 7877 var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g; 7878 7879 var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g; 7880 7881 var formatFunctions = {}; 7882 7883 var formatTokenFunctions = {}; 7884 7885 // token: 'M' 7886 // padded: ['MM', 2] 7887 // ordinal: 'Mo' 7888 // callback: function () { this.month() + 1 } 7889 function addFormatToken(token, padded, ordinal, callback) { 7890 var func = callback; 7891 if (typeof callback === 'string') { 7892 func = function () { 7893 return this[callback](); 7894 }; 7895 } 7896 if (token) { 7897 formatTokenFunctions[token] = func; 7898 } 7899 if (padded) { 7900 formatTokenFunctions[padded[0]] = function () { 7901 return zeroFill(func.apply(this, arguments), padded[1], padded[2]); 7902 }; 7903 } 7904 if (ordinal) { 7905 formatTokenFunctions[ordinal] = function () { 7906 return this.localeData().ordinal(func.apply(this, arguments), token); 7907 }; 7908 } 7909 } 7910 7911 function removeFormattingTokens(input) { 7912 if (input.match(/\[[\s\S]/)) { 7913 return input.replace(/^\[|\]$/g, ''); 7914 } 7915 return input.replace(/\\/g, ''); 7916 } 7917 7918 function makeFormatFunction(format) { 7919 var array = format.match(formattingTokens), i, length; 7920 7921 for (i = 0, length = array.length; i < length; i++) { 7922 if (formatTokenFunctions[array[i]]) { 7923 array[i] = formatTokenFunctions[array[i]]; 7924 } else { 7925 array[i] = removeFormattingTokens(array[i]); 7926 } 7927 } 7928 7929 return function (mom) { 7930 var output = '', i; 7931 for (i = 0; i < length; i++) { 7932 output += isFunction(array[i]) ? array[i].call(mom, format) : array[i]; 7933 } 7934 return output; 7935 }; 7936 } 7937 7938 // format date using native date object 7939 function formatMoment(m, format) { 7940 if (!m.isValid()) { 7941 return m.localeData().invalidDate(); 7942 } 7943 7944 format = expandFormat(format, m.localeData()); 7945 formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format); 7946 7947 return formatFunctions[format](m); 7948 } 7949 7950 function expandFormat(format, locale) { 7951 var i = 5; 7952 7953 function replaceLongDateFormatTokens(input) { 7954 return locale.longDateFormat(input) || input; 7955 } 7956 7957 localFormattingTokens.lastIndex = 0; 7958 while (i >= 0 && localFormattingTokens.test(format)) { 7959 format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); 7960 localFormattingTokens.lastIndex = 0; 7961 i -= 1; 7962 } 7963 7964 return format; 7965 } 7966 7967 var match1 = /\d/; // 0 - 9 7968 var match2 = /\d\d/; // 00 - 99 7969 var match3 = /\d{3}/; // 000 - 999 7970 var match4 = /\d{4}/; // 0000 - 9999 7971 var match6 = /[+-]?\d{6}/; // -999999 - 999999 7972 var match1to2 = /\d\d?/; // 0 - 99 7973 var match3to4 = /\d\d\d\d?/; // 999 - 9999 7974 var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999 7975 var match1to3 = /\d{1,3}/; // 0 - 999 7976 var match1to4 = /\d{1,4}/; // 0 - 9999 7977 var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999 7978 7979 var matchUnsigned = /\d+/; // 0 - inf 7980 var matchSigned = /[+-]?\d+/; // -inf - inf 7981 7982 var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z 7983 var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z 7984 7985 var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123 7986 7987 // any word (or two) characters or numbers including two/three word month in arabic. 7988 // includes scottish gaelic two word and hyphenated months 7989 var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i; 7990 7991 var regexes = {}; 7992 7993 function addRegexToken(token, regex, strictRegex) { 7994 regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) { 7995 return (isStrict && strictRegex) ? strictRegex : regex; 7996 }; 7997 } 7998 7999 function getParseRegexForToken(token, config) { 8000 if (!hasOwnProp(regexes, token)) { 8001 return new RegExp(unescapeFormat(token)); 8002 } 8003 8004 return regexes[token](config._strict, config._locale); 8005 } 8006 8007 // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript 8008 function unescapeFormat(s) { 8009 return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { 8010 return p1 || p2 || p3 || p4; 8011 })); 8012 } 8013 8014 function regexEscape(s) { 8015 return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); 8016 } 8017 8018 var tokens = {}; 8019 8020 function addParseToken(token, callback) { 8021 var i, func = callback; 8022 if (typeof token === 'string') { 8023 token = [token]; 8024 } 8025 if (isNumber(callback)) { 8026 func = function (input, array) { 8027 array[callback] = toInt(input); 8028 }; 8029 } 8030 for (i = 0; i < token.length; i++) { 8031 tokens[token[i]] = func; 8032 } 8033 } 8034 8035 function addWeekParseToken(token, callback) { 8036 addParseToken(token, function (input, array, config, token) { 8037 config._w = config._w || {}; 8038 callback(input, config._w, config, token); 8039 }); 8040 } 8041 8042 function addTimeToArrayFromToken(token, input, config) { 8043 if (input != null && hasOwnProp(tokens, token)) { 8044 tokens[token](input, config._a, config, token); 8045 } 8046 } 8047 8048 var YEAR = 0; 8049 var MONTH = 1; 8050 var DATE = 2; 8051 var HOUR = 3; 8052 var MINUTE = 4; 8053 var SECOND = 5; 8054 var MILLISECOND = 6; 8055 var WEEK = 7; 8056 var WEEKDAY = 8; 8057 8058 // FORMATTING 8059 8060 addFormatToken('Y', 0, 0, function () { 8061 var y = this.year(); 8062 return y <= 9999 ? '' + y : '+' + y; 8063 }); 8064 8065 addFormatToken(0, ['YY', 2], 0, function () { 8066 return this.year() % 100; 8067 }); 8068 8069 addFormatToken(0, ['YYYY', 4], 0, 'year'); 8070 addFormatToken(0, ['YYYYY', 5], 0, 'year'); 8071 addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); 8072 8073 // ALIASES 8074 8075 addUnitAlias('year', 'y'); 8076 8077 // PRIORITIES 8078 8079 addUnitPriority('year', 1); 8080 8081 // PARSING 8082 8083 addRegexToken('Y', matchSigned); 8084 addRegexToken('YY', match1to2, match2); 8085 addRegexToken('YYYY', match1to4, match4); 8086 addRegexToken('YYYYY', match1to6, match6); 8087 addRegexToken('YYYYYY', match1to6, match6); 8088 8089 addParseToken(['YYYYY', 'YYYYYY'], YEAR); 8090 addParseToken('YYYY', function (input, array) { 8091 array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input); 8092 }); 8093 addParseToken('YY', function (input, array) { 8094 array[YEAR] = hooks.parseTwoDigitYear(input); 8095 }); 8096 addParseToken('Y', function (input, array) { 8097 array[YEAR] = parseInt(input, 10); 8098 }); 8099 8100 // HELPERS 8101 8102 function daysInYear(year) { 8103 return isLeapYear(year) ? 366 : 365; 8104 } 8105 8106 function isLeapYear(year) { 8107 return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; 8108 } 8109 8110 // HOOKS 8111 8112 hooks.parseTwoDigitYear = function (input) { 8113 return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); 8114 }; 8115 8116 // MOMENTS 8117 8118 var getSetYear = makeGetSet('FullYear', true); 8119 8120 function getIsLeapYear() { 8121 return isLeapYear(this.year()); 8122 } 8123 8124 function makeGetSet(unit, keepTime) { 8125 return function (value) { 8126 if (value != null) { 8127 set$1(this, unit, value); 8128 hooks.updateOffset(this, keepTime); 8129 return this; 8130 } else { 8131 return get(this, unit); 8132 } 8133 }; 8134 } 8135 8136 function get(mom, unit) { 8137 return mom.isValid() ? 8138 mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN; 8139 } 8140 8141 function set$1(mom, unit, value) { 8142 if (mom.isValid() && !isNaN(value)) { 8143 if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) { 8144 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month())); 8145 } 8146 else { 8147 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); 8148 } 8149 } 8150 } 8151 8152 // MOMENTS 8153 8154 function stringGet(units) { 8155 units = normalizeUnits(units); 8156 if (isFunction(this[units])) { 8157 return this[units](); 8158 } 8159 return this; 8160 } 8161 8162 8163 function stringSet(units, value) { 8164 if (typeof units === 'object') { 8165 units = normalizeObjectUnits(units); 8166 var prioritized = getPrioritizedUnits(units); 8167 for (var i = 0; i < prioritized.length; i++) { 8168 this[prioritized[i].unit](units[prioritized[i].unit]); 8169 } 8170 } else { 8171 units = normalizeUnits(units); 8172 if (isFunction(this[units])) { 8173 return this[units](value); 8174 } 8175 } 8176 return this; 8177 } 8178 8179 function mod(n, x) { 8180 return ((n % x) + x) % x; 8181 } 8182 8183 var indexOf; 8184 8185 if (Array.prototype.indexOf) { 8186 indexOf = Array.prototype.indexOf; 8187 } else { 8188 indexOf = function (o) { 8189 // I know 8190 var i; 8191 for (i = 0; i < this.length; ++i) { 8192 if (this[i] === o) { 8193 return i; 8194 } 8195 } 8196 return -1; 8197 }; 8198 } 8199 8200 function daysInMonth(year, month) { 8201 if (isNaN(year) || isNaN(month)) { 8202 return NaN; 8203 } 8204 var modMonth = mod(month, 12); 8205 year += (month - modMonth) / 12; 8206 return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2); 8207 } 8208 8209 // FORMATTING 8210 8211 addFormatToken('M', ['MM', 2], 'Mo', function () { 8212 return this.month() + 1; 8213 }); 8214 8215 addFormatToken('MMM', 0, 0, function (format) { 8216 return this.localeData().monthsShort(this, format); 8217 }); 8218 8219 addFormatToken('MMMM', 0, 0, function (format) { 8220 return this.localeData().months(this, format); 8221 }); 8222 8223 // ALIASES 8224 8225 addUnitAlias('month', 'M'); 8226 8227 // PRIORITY 8228 8229 addUnitPriority('month', 8); 8230 8231 // PARSING 8232 8233 addRegexToken('M', match1to2); 8234 addRegexToken('MM', match1to2, match2); 8235 addRegexToken('MMM', function (isStrict, locale) { 8236 return locale.monthsShortRegex(isStrict); 8237 }); 8238 addRegexToken('MMMM', function (isStrict, locale) { 8239 return locale.monthsRegex(isStrict); 8240 }); 8241 8242 addParseToken(['M', 'MM'], function (input, array) { 8243 array[MONTH] = toInt(input) - 1; 8244 }); 8245 8246 addParseToken(['MMM', 'MMMM'], function (input, array, config, token) { 8247 var month = config._locale.monthsParse(input, token, config._strict); 8248 // if we didn't find a month name, mark the date as invalid. 8249 if (month != null) { 8250 array[MONTH] = month; 8251 } else { 8252 getParsingFlags(config).invalidMonth = input; 8253 } 8254 }); 8255 8256 // LOCALES 8257 8258 var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/; 8259 var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'); 8260 function localeMonths(m, format) { 8261 if (!m) { 8262 return isArray(this._months) ? this._months : 8263 this._months['standalone']; 8264 } 8265 return isArray(this._months) ? this._months[m.month()] : 8266 this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()]; 8267 } 8268 8269 var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'); 8270 function localeMonthsShort(m, format) { 8271 if (!m) { 8272 return isArray(this._monthsShort) ? this._monthsShort : 8273 this._monthsShort['standalone']; 8274 } 8275 return isArray(this._monthsShort) ? this._monthsShort[m.month()] : 8276 this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()]; 8277 } 8278 8279 function handleStrictParse(monthName, format, strict) { 8280 var i, ii, mom, llc = monthName.toLocaleLowerCase(); 8281 if (!this._monthsParse) { 8282 // this is not used 8283 this._monthsParse = []; 8284 this._longMonthsParse = []; 8285 this._shortMonthsParse = []; 8286 for (i = 0; i < 12; ++i) { 8287 mom = createUTC([2000, i]); 8288 this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase(); 8289 this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase(); 8290 } 8291 } 8292 8293 if (strict) { 8294 if (format === 'MMM') { 8295 ii = indexOf.call(this._shortMonthsParse, llc); 8296 return ii !== -1 ? ii : null; 8297 } else { 8298 ii = indexOf.call(this._longMonthsParse, llc); 8299 return ii !== -1 ? ii : null; 8300 } 8301 } else { 8302 if (format === 'MMM') { 8303 ii = indexOf.call(this._shortMonthsParse, llc); 8304 if (ii !== -1) { 8305 return ii; 8306 } 8307 ii = indexOf.call(this._longMonthsParse, llc); 8308 return ii !== -1 ? ii : null; 8309 } else { 8310 ii = indexOf.call(this._longMonthsParse, llc); 8311 if (ii !== -1) { 8312 return ii; 8313 } 8314 ii = indexOf.call(this._shortMonthsParse, llc); 8315 return ii !== -1 ? ii : null; 8316 } 8317 } 8318 } 8319 8320 function localeMonthsParse(monthName, format, strict) { 8321 var i, mom, regex; 8322 8323 if (this._monthsParseExact) { 8324 return handleStrictParse.call(this, monthName, format, strict); 8325 } 8326 8327 if (!this._monthsParse) { 8328 this._monthsParse = []; 8329 this._longMonthsParse = []; 8330 this._shortMonthsParse = []; 8331 } 8332 8333 // TODO: add sorting 8334 // Sorting makes sure if one month (or abbr) is a prefix of another 8335 // see sorting in computeMonthsParse 8336 for (i = 0; i < 12; i++) { 8337 // make the regex if we don't have it already 8338 mom = createUTC([2000, i]); 8339 if (strict && !this._longMonthsParse[i]) { 8340 this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i'); 8341 this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i'); 8342 } 8343 if (!strict && !this._monthsParse[i]) { 8344 regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); 8345 this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); 8346 } 8347 // test the regex 8348 if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) { 8349 return i; 8350 } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) { 8351 return i; 8352 } else if (!strict && this._monthsParse[i].test(monthName)) { 8353 return i; 8354 } 8355 } 8356 } 8357 8358 // MOMENTS 8359 8360 function setMonth(mom, value) { 8361 var dayOfMonth; 8362 8363 if (!mom.isValid()) { 8364 // No op 8365 return mom; 8366 } 8367 8368 if (typeof value === 'string') { 8369 if (/^\d+$/.test(value)) { 8370 value = toInt(value); 8371 } else { 8372 value = mom.localeData().monthsParse(value); 8373 // TODO: Another silent failure? 8374 if (!isNumber(value)) { 8375 return mom; 8376 } 8377 } 8378 } 8379 8380 dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value)); 8381 mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); 8382 return mom; 8383 } 8384 8385 function getSetMonth(value) { 8386 if (value != null) { 8387 setMonth(this, value); 8388 hooks.updateOffset(this, true); 8389 return this; 8390 } else { 8391 return get(this, 'Month'); 8392 } 8393 } 8394 8395 function getDaysInMonth() { 8396 return daysInMonth(this.year(), this.month()); 8397 } 8398 8399 var defaultMonthsShortRegex = matchWord; 8400 function monthsShortRegex(isStrict) { 8401 if (this._monthsParseExact) { 8402 if (!hasOwnProp(this, '_monthsRegex')) { 8403 computeMonthsParse.call(this); 8404 } 8405 if (isStrict) { 8406 return this._monthsShortStrictRegex; 8407 } else { 8408 return this._monthsShortRegex; 8409 } 8410 } else { 8411 if (!hasOwnProp(this, '_monthsShortRegex')) { 8412 this._monthsShortRegex = defaultMonthsShortRegex; 8413 } 8414 return this._monthsShortStrictRegex && isStrict ? 8415 this._monthsShortStrictRegex : this._monthsShortRegex; 8416 } 8417 } 8418 8419 var defaultMonthsRegex = matchWord; 8420 function monthsRegex(isStrict) { 8421 if (this._monthsParseExact) { 8422 if (!hasOwnProp(this, '_monthsRegex')) { 8423 computeMonthsParse.call(this); 8424 } 8425 if (isStrict) { 8426 return this._monthsStrictRegex; 8427 } else { 8428 return this._monthsRegex; 8429 } 8430 } else { 8431 if (!hasOwnProp(this, '_monthsRegex')) { 8432 this._monthsRegex = defaultMonthsRegex; 8433 } 8434 return this._monthsStrictRegex && isStrict ? 8435 this._monthsStrictRegex : this._monthsRegex; 8436 } 8437 } 8438 8439 function computeMonthsParse() { 8440 function cmpLenRev(a, b) { 8441 return b.length - a.length; 8442 } 8443 8444 var shortPieces = [], longPieces = [], mixedPieces = [], 8445 i, mom; 8446 for (i = 0; i < 12; i++) { 8447 // make the regex if we don't have it already 8448 mom = createUTC([2000, i]); 8449 shortPieces.push(this.monthsShort(mom, '')); 8450 longPieces.push(this.months(mom, '')); 8451 mixedPieces.push(this.months(mom, '')); 8452 mixedPieces.push(this.monthsShort(mom, '')); 8453 } 8454 // Sorting makes sure if one month (or abbr) is a prefix of another it 8455 // will match the longer piece. 8456 shortPieces.sort(cmpLenRev); 8457 longPieces.sort(cmpLenRev); 8458 mixedPieces.sort(cmpLenRev); 8459 for (i = 0; i < 12; i++) { 8460 shortPieces[i] = regexEscape(shortPieces[i]); 8461 longPieces[i] = regexEscape(longPieces[i]); 8462 } 8463 for (i = 0; i < 24; i++) { 8464 mixedPieces[i] = regexEscape(mixedPieces[i]); 8465 } 8466 8467 this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); 8468 this._monthsShortRegex = this._monthsRegex; 8469 this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); 8470 this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); 8471 } 8472 8473 function createDate(y, m, d, h, M, s, ms) { 8474 // can't just apply() to create a date: 8475 // https://stackoverflow.com/q/181348 8476 var date; 8477 // the date constructor remaps years 0-99 to 1900-1999 8478 if (y < 100 && y >= 0) { 8479 // preserve leap years using a full 400 year cycle, then reset 8480 date = new Date(y + 400, m, d, h, M, s, ms); 8481 if (isFinite(date.getFullYear())) { 8482 date.setFullYear(y); 8483 } 8484 } else { 8485 date = new Date(y, m, d, h, M, s, ms); 8486 } 8487 8488 return date; 8489 } 8490 8491 function createUTCDate(y) { 8492 var date; 8493 // the Date.UTC function remaps years 0-99 to 1900-1999 8494 if (y < 100 && y >= 0) { 8495 var args = Array.prototype.slice.call(arguments); 8496 // preserve leap years using a full 400 year cycle, then reset 8497 args[0] = y + 400;
vendor: 3,026 bytes, lines 8498-8592
8498 date = new Date(Date.UTC.apply(null, args)); 8499 if (isFinite(date.getUTCFullYear())) { 8500 date.setUTCFullYear(y); 8501 } 8502 } else { 8503 date = new Date(Date.UTC.apply(null, arguments)); 8504 } 8505 8506 return date; 8507 } 8508 8509 // start-of-first-week - start-of-year 8510 function firstWeekOffset(year, dow, doy) { 8511 var // first-week day -- which january is always in the first week (4 for iso, 1 for other) 8512 fwd = 7 + dow - doy, 8513 // first-week day local weekday -- which local weekday is fwd 8514 fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7; 8515 8516 return -fwdlw + fwd - 1; 8517 } 8518 8519 // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday 8520 function dayOfYearFromWeeks(year, week, weekday, dow, doy) { 8521 var localWeekday = (7 + weekday - dow) % 7, 8522 weekOffset = firstWeekOffset(year, dow, doy), 8523 dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset, 8524 resYear, resDayOfYear; 8525 8526 if (dayOfYear <= 0) { 8527 resYear = year - 1; 8528 resDayOfYear = daysInYear(resYear) + dayOfYear; 8529 } else if (dayOfYear > daysInYear(year)) { 8530 resYear = year + 1; 8531 resDayOfYear = dayOfYear - daysInYear(year); 8532 } else { 8533 resYear = year; 8534 resDayOfYear = dayOfYear; 8535 } 8536 8537 return { 8538 year: resYear, 8539 dayOfYear: resDayOfYear 8540 }; 8541 } 8542 8543 function weekOfYear(mom, dow, doy) { 8544 var weekOffset = firstWeekOffset(mom.year(), dow, doy), 8545 week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1, 8546 resWeek, resYear; 8547 8548 if (week < 1) { 8549 resYear = mom.year() - 1; 8550 resWeek = week + weeksInYear(resYear, dow, doy); 8551 } else if (week > weeksInYear(mom.year(), dow, doy)) { 8552 resWeek = week - weeksInYear(mom.year(), dow, doy); 8553 resYear = mom.year() + 1; 8554 } else { 8555 resYear = mom.year(); 8556 resWeek = week; 8557 } 8558 8559 return { 8560 week: resWeek, 8561 year: resYear 8562 }; 8563 } 8564 8565 function weeksInYear(year, dow, doy) { 8566 var weekOffset = firstWeekOffset(year, dow, doy), 8567 weekOffsetNext = firstWeekOffset(year + 1, dow, doy); 8568 return (daysInYear(year) - weekOffset + weekOffsetNext) / 7; 8569 } 8570 8571 // FORMATTING 8572 8573 addFormatToken('w', ['ww', 2], 'wo', 'week'); 8574 addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); 8575 8576 // ALIASES 8577 8578 addUnitAlias('week', 'w'); 8579 addUnitAlias('isoWeek', 'W'); 8580 8581 // PRIORITIES 8582 8583 addUnitPriority('week', 5); 8584 addUnitPriority('isoWeek', 5); 8585 8586 // PARSING 8587 8588 addRegexToken('w', match1to2); 8589 addRegexToken('ww', match1to2, match2); 8590 addRegexToken('W', match1to2); 8591 addRegexToken('WW', match1to2, match2); 8592
vendor: 83,543 bytes, lines 8593-10993
8593 addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) { 8594 week[token.substr(0, 1)] = toInt(input); 8595 }); 8596 8597 // HELPERS 8598 8599 // LOCALES 8600 8601 function localeWeek(mom) { 8602 return weekOfYear(mom, this._week.dow, this._week.doy).week; 8603 } 8604 8605 var defaultLocaleWeek = { 8606 dow: 0, // Sunday is the first day of the week. 8607 doy: 6 // The week that contains Jan 6th is the first week of the year. 8608 }; 8609 8610 function localeFirstDayOfWeek() { 8611 return this._week.dow; 8612 } 8613 8614 function localeFirstDayOfYear() { 8615 return this._week.doy; 8616 } 8617 8618 // MOMENTS 8619 8620 function getSetWeek(input) { 8621 var week = this.localeData().week(this); 8622 return input == null ? week : this.add((input - week) * 7, 'd'); 8623 } 8624 8625 function getSetISOWeek(input) { 8626 var week = weekOfYear(this, 1, 4).week; 8627 return input == null ? week : this.add((input - week) * 7, 'd'); 8628 } 8629 8630 // FORMATTING 8631 8632 addFormatToken('d', 0, 'do', 'day'); 8633 8634 addFormatToken('dd', 0, 0, function (format) { 8635 return this.localeData().weekdaysMin(this, format); 8636 }); 8637 8638 addFormatToken('ddd', 0, 0, function (format) { 8639 return this.localeData().weekdaysShort(this, format); 8640 }); 8641 8642 addFormatToken('dddd', 0, 0, function (format) { 8643 return this.localeData().weekdays(this, format); 8644 }); 8645 8646 addFormatToken('e', 0, 0, 'weekday'); 8647 addFormatToken('E', 0, 0, 'isoWeekday'); 8648 8649 // ALIASES 8650 8651 addUnitAlias('day', 'd'); 8652 addUnitAlias('weekday', 'e'); 8653 addUnitAlias('isoWeekday', 'E'); 8654 8655 // PRIORITY 8656 addUnitPriority('day', 11); 8657 addUnitPriority('weekday', 11); 8658 addUnitPriority('isoWeekday', 11); 8659 8660 // PARSING 8661 8662 addRegexToken('d', match1to2); 8663 addRegexToken('e', match1to2); 8664 addRegexToken('E', match1to2); 8665 addRegexToken('dd', function (isStrict, locale) { 8666 return locale.weekdaysMinRegex(isStrict); 8667 }); 8668 addRegexToken('ddd', function (isStrict, locale) { 8669 return locale.weekdaysShortRegex(isStrict); 8670 }); 8671 addRegexToken('dddd', function (isStrict, locale) { 8672 return locale.weekdaysRegex(isStrict); 8673 }); 8674 8675 addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) { 8676 var weekday = config._locale.weekdaysParse(input, token, config._strict); 8677 // if we didn't get a weekday name, mark the date as invalid 8678 if (weekday != null) { 8679 week.d = weekday; 8680 } else { 8681 getParsingFlags(config).invalidWeekday = input; 8682 } 8683 }); 8684 8685 addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) { 8686 week[token] = toInt(input); 8687 }); 8688 8689 // HELPERS 8690 8691 function parseWeekday(input, locale) { 8692 if (typeof input !== 'string') { 8693 return input; 8694 } 8695 8696 if (!isNaN(input)) { 8697 return parseInt(input, 10); 8698 } 8699 8700 input = locale.weekdaysParse(input); 8701 if (typeof input === 'number') { 8702 return input; 8703 } 8704 8705 return null; 8706 } 8707 8708 function parseIsoWeekday(input, locale) { 8709 if (typeof input === 'string') { 8710 return locale.weekdaysParse(input) % 7 || 7; 8711 } 8712 return isNaN(input) ? null : input; 8713 } 8714 8715 // LOCALES 8716 function shiftWeekdays(ws, n) { 8717 return ws.slice(n, 7).concat(ws.slice(0, n)); 8718 } 8719 8720 var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'); 8721 function localeWeekdays(m, format) { 8722 var weekdays = isArray(this._weekdays) ? this._weekdays : 8723 this._weekdays[(m && m !== true && this._weekdays.isFormat.test(format)) ? 'format' : 'standalone']; 8724 return (m === true) ? shiftWeekdays(weekdays, this._week.dow) 8725 : (m) ? weekdays[m.day()] : weekdays; 8726 } 8727 8728 var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'); 8729 function localeWeekdaysShort(m) { 8730 return (m === true) ? shiftWeekdays(this._weekdaysShort, this._week.dow) 8731 : (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort; 8732 } 8733 8734 var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'); 8735 function localeWeekdaysMin(m) { 8736 return (m === true) ? shiftWeekdays(this._weekdaysMin, this._week.dow) 8737 : (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin; 8738 } 8739 8740 function handleStrictParse$1(weekdayName, format, strict) { 8741 var i, ii, mom, llc = weekdayName.toLocaleLowerCase(); 8742 if (!this._weekdaysParse) { 8743 this._weekdaysParse = []; 8744 this._shortWeekdaysParse = []; 8745 this._minWeekdaysParse = []; 8746 8747 for (i = 0; i < 7; ++i) { 8748 mom = createUTC([2000, 1]).day(i); 8749 this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase(); 8750 this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase(); 8751 this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase(); 8752 } 8753 } 8754 8755 if (strict) { 8756 if (format === 'dddd') { 8757 ii = indexOf.call(this._weekdaysParse, llc); 8758 return ii !== -1 ? ii : null; 8759 } else if (format === 'ddd') { 8760 ii = indexOf.call(this._shortWeekdaysParse, llc); 8761 return ii !== -1 ? ii : null; 8762 } else { 8763 ii = indexOf.call(this._minWeekdaysParse, llc); 8764 return ii !== -1 ? ii : null; 8765 } 8766 } else { 8767 if (format === 'dddd') { 8768 ii = indexOf.call(this._weekdaysParse, llc); 8769 if (ii !== -1) { 8770 return ii; 8771 } 8772 ii = indexOf.call(this._shortWeekdaysParse, llc); 8773 if (ii !== -1) { 8774 return ii; 8775 } 8776 ii = indexOf.call(this._minWeekdaysParse, llc); 8777 return ii !== -1 ? ii : null; 8778 } else if (format === 'ddd') { 8779 ii = indexOf.call(this._shortWeekdaysParse, llc); 8780 if (ii !== -1) { 8781 return ii; 8782 } 8783 ii = indexOf.call(this._weekdaysParse, llc); 8784 if (ii !== -1) { 8785 return ii; 8786 } 8787 ii = indexOf.call(this._minWeekdaysParse, llc); 8788 return ii !== -1 ? ii : null; 8789 } else { 8790 ii = indexOf.call(this._minWeekdaysParse, llc); 8791 if (ii !== -1) { 8792 return ii; 8793 } 8794 ii = indexOf.call(this._weekdaysParse, llc); 8795 if (ii !== -1) { 8796 return ii; 8797 } 8798 ii = indexOf.call(this._shortWeekdaysParse, llc); 8799 return ii !== -1 ? ii : null; 8800 } 8801 } 8802 } 8803 8804 function localeWeekdaysParse(weekdayName, format, strict) { 8805 var i, mom, regex; 8806 8807 if (this._weekdaysParseExact) { 8808 return handleStrictParse$1.call(this, weekdayName, format, strict); 8809 } 8810 8811 if (!this._weekdaysParse) { 8812 this._weekdaysParse = []; 8813 this._minWeekdaysParse = []; 8814 this._shortWeekdaysParse = []; 8815 this._fullWeekdaysParse = []; 8816 } 8817 8818 for (i = 0; i < 7; i++) { 8819 // make the regex if we don't have it already 8820 8821 mom = createUTC([2000, 1]).day(i); 8822 if (strict && !this._fullWeekdaysParse[i]) { 8823 this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i'); 8824 this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i'); 8825 this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i'); 8826 } 8827 if (!this._weekdaysParse[i]) { 8828 regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); 8829 this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); 8830 } 8831 // test the regex 8832 if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) { 8833 return i; 8834 } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) { 8835 return i; 8836 } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) { 8837 return i; 8838 } else if (!strict && this._weekdaysParse[i].test(weekdayName)) { 8839 return i; 8840 } 8841 } 8842 } 8843 8844 // MOMENTS 8845 8846 function getSetDayOfWeek(input) { 8847 if (!this.isValid()) { 8848 return input != null ? this : NaN; 8849 } 8850 var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); 8851 if (input != null) { 8852 input = parseWeekday(input, this.localeData()); 8853 return this.add(input - day, 'd'); 8854 } else { 8855 return day; 8856 } 8857 } 8858 8859 function getSetLocaleDayOfWeek(input) { 8860 if (!this.isValid()) { 8861 return input != null ? this : NaN; 8862 } 8863 var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; 8864 return input == null ? weekday : this.add(input - weekday, 'd'); 8865 } 8866 8867 function getSetISODayOfWeek(input) { 8868 if (!this.isValid()) { 8869 return input != null ? this : NaN; 8870 } 8871 8872 // behaves the same as moment#day except 8873 // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) 8874 // as a setter, sunday should belong to the previous week. 8875 8876 if (input != null) { 8877 var weekday = parseIsoWeekday(input, this.localeData()); 8878 return this.day(this.day() % 7 ? weekday : weekday - 7); 8879 } else { 8880 return this.day() || 7; 8881 } 8882 } 8883 8884 var defaultWeekdaysRegex = matchWord; 8885 function weekdaysRegex(isStrict) { 8886 if (this._weekdaysParseExact) { 8887 if (!hasOwnProp(this, '_weekdaysRegex')) { 8888 computeWeekdaysParse.call(this); 8889 } 8890 if (isStrict) { 8891 return this._weekdaysStrictRegex; 8892 } else { 8893 return this._weekdaysRegex; 8894 } 8895 } else { 8896 if (!hasOwnProp(this, '_weekdaysRegex')) { 8897 this._weekdaysRegex = defaultWeekdaysRegex; 8898 } 8899 return this._weekdaysStrictRegex && isStrict ? 8900 this._weekdaysStrictRegex : this._weekdaysRegex; 8901 } 8902 } 8903 8904 var defaultWeekdaysShortRegex = matchWord; 8905 function weekdaysShortRegex(isStrict) { 8906 if (this._weekdaysParseExact) { 8907 if (!hasOwnProp(this, '_weekdaysRegex')) { 8908 computeWeekdaysParse.call(this); 8909 } 8910 if (isStrict) { 8911 return this._weekdaysShortStrictRegex; 8912 } else { 8913 return this._weekdaysShortRegex; 8914 } 8915 } else { 8916 if (!hasOwnProp(this, '_weekdaysShortRegex')) { 8917 this._weekdaysShortRegex = defaultWeekdaysShortRegex; 8918 } 8919 return this._weekdaysShortStrictRegex && isStrict ? 8920 this._weekdaysShortStrictRegex : this._weekdaysShortRegex; 8921 } 8922 } 8923 8924 var defaultWeekdaysMinRegex = matchWord; 8925 function weekdaysMinRegex(isStrict) { 8926 if (this._weekdaysParseExact) { 8927 if (!hasOwnProp(this, '_weekdaysRegex')) { 8928 computeWeekdaysParse.call(this); 8929 } 8930 if (isStrict) { 8931 return this._weekdaysMinStrictRegex; 8932 } else { 8933 return this._weekdaysMinRegex; 8934 } 8935 } else { 8936 if (!hasOwnProp(this, '_weekdaysMinRegex')) { 8937 this._weekdaysMinRegex = defaultWeekdaysMinRegex; 8938 } 8939 return this._weekdaysMinStrictRegex && isStrict ? 8940 this._weekdaysMinStrictRegex : this._weekdaysMinRegex; 8941 } 8942 } 8943 8944 8945 function computeWeekdaysParse() { 8946 function cmpLenRev(a, b) { 8947 return b.length - a.length; 8948 } 8949 8950 var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [], 8951 i, mom, minp, shortp, longp; 8952 for (i = 0; i < 7; i++) { 8953 // make the regex if we don't have it already 8954 mom = createUTC([2000, 1]).day(i); 8955 minp = this.weekdaysMin(mom, ''); 8956 shortp = this.weekdaysShort(mom, ''); 8957 longp = this.weekdays(mom, ''); 8958 minPieces.push(minp); 8959 shortPieces.push(shortp); 8960 longPieces.push(longp); 8961 mixedPieces.push(minp); 8962 mixedPieces.push(shortp); 8963 mixedPieces.push(longp); 8964 } 8965 // Sorting makes sure if one weekday (or abbr) is a prefix of another it 8966 // will match the longer piece. 8967 minPieces.sort(cmpLenRev); 8968 shortPieces.sort(cmpLenRev); 8969 longPieces.sort(cmpLenRev); 8970 mixedPieces.sort(cmpLenRev); 8971 for (i = 0; i < 7; i++) { 8972 shortPieces[i] = regexEscape(shortPieces[i]); 8973 longPieces[i] = regexEscape(longPieces[i]); 8974 mixedPieces[i] = regexEscape(mixedPieces[i]); 8975 } 8976 8977 this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); 8978 this._weekdaysShortRegex = this._weekdaysRegex; 8979 this._weekdaysMinRegex = this._weekdaysRegex; 8980 8981 this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); 8982 this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); 8983 this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i'); 8984 } 8985 8986 // FORMATTING 8987 8988 function hFormat() { 8989 return this.hours() % 12 || 12; 8990 } 8991 8992 function kFormat() { 8993 return this.hours() || 24; 8994 } 8995 8996 addFormatToken('H', ['HH', 2], 0, 'hour'); 8997 addFormatToken('h', ['hh', 2], 0, hFormat); 8998 addFormatToken('k', ['kk', 2], 0, kFormat); 8999 9000 addFormatToken('hmm', 0, 0, function () { 9001 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2); 9002 }); 9003 9004 addFormatToken('hmmss', 0, 0, function () { 9005 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + 9006 zeroFill(this.seconds(), 2); 9007 }); 9008 9009 addFormatToken('Hmm', 0, 0, function () { 9010 return '' + this.hours() + zeroFill(this.minutes(), 2); 9011 }); 9012 9013 addFormatToken('Hmmss', 0, 0, function () { 9014 return '' + this.hours() + zeroFill(this.minutes(), 2) + 9015 zeroFill(this.seconds(), 2); 9016 }); 9017 9018 function meridiem(token, lowercase) { 9019 addFormatToken(token, 0, 0, function () { 9020 return this.localeData().meridiem(this.hours(), this.minutes(), lowercase); 9021 }); 9022 } 9023 9024 meridiem('a', true); 9025 meridiem('A', false); 9026 9027 // ALIASES 9028 9029 addUnitAlias('hour', 'h'); 9030 9031 // PRIORITY 9032 addUnitPriority('hour', 13); 9033 9034 // PARSING 9035 9036 function matchMeridiem(isStrict, locale) { 9037 return locale._meridiemParse; 9038 } 9039 9040 addRegexToken('a', matchMeridiem); 9041 addRegexToken('A', matchMeridiem); 9042 addRegexToken('H', match1to2); 9043 addRegexToken('h', match1to2); 9044 addRegexToken('k', match1to2); 9045 addRegexToken('HH', match1to2, match2); 9046 addRegexToken('hh', match1to2, match2); 9047 addRegexToken('kk', match1to2, match2); 9048 9049 addRegexToken('hmm', match3to4); 9050 addRegexToken('hmmss', match5to6); 9051 addRegexToken('Hmm', match3to4); 9052 addRegexToken('Hmmss', match5to6); 9053 9054 addParseToken(['H', 'HH'], HOUR); 9055 addParseToken(['k', 'kk'], function (input, array, config) { 9056 var kInput = toInt(input); 9057 array[HOUR] = kInput === 24 ? 0 : kInput; 9058 }); 9059 addParseToken(['a', 'A'], function (input, array, config) { 9060 config._isPm = config._locale.isPM(input); 9061 config._meridiem = input; 9062 }); 9063 addParseToken(['h', 'hh'], function (input, array, config) { 9064 array[HOUR] = toInt(input); 9065 getParsingFlags(config).bigHour = true; 9066 }); 9067 addParseToken('hmm', function (input, array, config) { 9068 var pos = input.length - 2; 9069 array[HOUR] = toInt(input.substr(0, pos)); 9070 array[MINUTE] = toInt(input.substr(pos)); 9071 getParsingFlags(config).bigHour = true; 9072 }); 9073 addParseToken('hmmss', function (input, array, config) { 9074 var pos1 = input.length - 4; 9075 var pos2 = input.length - 2; 9076 array[HOUR] = toInt(input.substr(0, pos1)); 9077 array[MINUTE] = toInt(input.substr(pos1, 2)); 9078 array[SECOND] = toInt(input.substr(pos2)); 9079 getParsingFlags(config).bigHour = true; 9080 }); 9081 addParseToken('Hmm', function (input, array, config) { 9082 var pos = input.length - 2; 9083 array[HOUR] = toInt(input.substr(0, pos)); 9084 array[MINUTE] = toInt(input.substr(pos)); 9085 }); 9086 addParseToken('Hmmss', function (input, array, config) { 9087 var pos1 = input.length - 4; 9088 var pos2 = input.length - 2; 9089 array[HOUR] = toInt(input.substr(0, pos1)); 9090 array[MINUTE] = toInt(input.substr(pos1, 2)); 9091 array[SECOND] = toInt(input.substr(pos2)); 9092 }); 9093 9094 // LOCALES 9095 9096 function localeIsPM(input) { 9097 // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays 9098 // Using charAt should be more compatible. 9099 return ((input + '').toLowerCase().charAt(0) === 'p'); 9100 } 9101 9102 var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i; 9103 function localeMeridiem(hours, minutes, isLower) { 9104 if (hours > 11) { 9105 return isLower ? 'pm' : 'PM'; 9106 } else { 9107 return isLower ? 'am' : 'AM'; 9108 } 9109 } 9110 9111 9112 // MOMENTS 9113 9114 // Setting the hour should keep the time, because the user explicitly 9115 // specified which hour they want. So trying to maintain the same hour (in 9116 // a new timezone) makes sense. Adding/subtracting hours does not follow 9117 // this rule. 9118 var getSetHour = makeGetSet('Hours', true); 9119 9120 var baseConfig = { 9121 calendar: defaultCalendar, 9122 longDateFormat: defaultLongDateFormat, 9123 invalidDate: defaultInvalidDate, 9124 ordinal: defaultOrdinal, 9125 dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse, 9126 relativeTime: defaultRelativeTime, 9127 9128 months: defaultLocaleMonths, 9129 monthsShort: defaultLocaleMonthsShort, 9130 9131 week: defaultLocaleWeek, 9132 9133 weekdays: defaultLocaleWeekdays, 9134 weekdaysMin: defaultLocaleWeekdaysMin, 9135 weekdaysShort: defaultLocaleWeekdaysShort, 9136 9137 meridiemParse: defaultLocaleMeridiemParse 9138 }; 9139 9140 // internal storage for locale config files 9141 var locales = {}; 9142 var localeFamilies = {}; 9143 var globalLocale; 9144 9145 function normalizeLocale(key) { 9146 return key ? key.toLowerCase().replace('_', '-') : key; 9147 } 9148 9149 // pick the locale from the array 9150 // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each 9151 // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root 9152 function chooseLocale(names) { 9153 var i = 0, j, next, locale, split; 9154 9155 while (i < names.length) { 9156 split = normalizeLocale(names[i]).split('-'); 9157 j = split.length; 9158 next = normalizeLocale(names[i + 1]); 9159 next = next ? next.split('-') : null; 9160 while (j > 0) { 9161 locale = loadLocale(split.slice(0, j).join('-')); 9162 if (locale) { 9163 return locale; 9164 } 9165 if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { 9166 //the next array item is better than a shallower substring of this one 9167 break; 9168 } 9169 j--; 9170 } 9171 i++; 9172 } 9173 return globalLocale; 9174 } 9175 9176 function loadLocale(name) { 9177 var oldLocale = null; 9178 // TODO: Find a better way to register and load all the locales in Node 9179 if (!locales[name] && (typeof module !== 'undefined') && 9180 module && module.exports) { 9181 try { 9182 oldLocale = globalLocale._abbr; 9183 var aliasedRequire = require; 9184 aliasedRequire('./locale/' + name); 9185 getSetGlobalLocale(oldLocale); 9186 } catch (e) { } 9187 } 9188 return locales[name]; 9189 } 9190 9191 // This function will load locale and then set the global locale. If 9192 // no arguments are passed in, it will simply return the current global 9193 // locale key. 9194 function getSetGlobalLocale(key, values) { 9195 var data; 9196 if (key) { 9197 if (isUndefined(values)) { 9198 data = getLocale(key); 9199 } 9200 else { 9201 data = defineLocale(key, values); 9202 } 9203 9204 if (data) { 9205 // moment.duration._locale = moment._locale = data; 9206 globalLocale = data; 9207 } 9208 else { 9209 if ((typeof console !== 'undefined') && console.warn) { 9210 //warn user if arguments are passed but the locale could not be set 9211 console.warn('Locale ' + key + ' not found. Did you forget to load it?'); 9212 } 9213 } 9214 } 9215 9216 return globalLocale._abbr; 9217 } 9218 9219 function defineLocale(name, config) { 9220 if (config !== null) { 9221 var locale, parentConfig = baseConfig; 9222 config.abbr = name; 9223 if (locales[name] != null) { 9224 deprecateSimple('defineLocaleOverride', 9225 'use moment.updateLocale(localeName, config) to change ' + 9226 'an existing locale. moment.defineLocale(localeName, ' + 9227 'config) should only be used for creating a new locale ' + 9228 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'); 9229 parentConfig = locales[name]._config; 9230 } else if (config.parentLocale != null) { 9231 if (locales[config.parentLocale] != null) { 9232 parentConfig = locales[config.parentLocale]._config; 9233 } else { 9234 locale = loadLocale(config.parentLocale); 9235 if (locale != null) { 9236 parentConfig = locale._config; 9237 } else { 9238 if (!localeFamilies[config.parentLocale]) { 9239 localeFamilies[config.parentLocale] = []; 9240 } 9241 localeFamilies[config.parentLocale].push({ 9242 name: name, 9243 config: config 9244 }); 9245 return null; 9246 } 9247 } 9248 } 9249 locales[name] = new Locale(mergeConfigs(parentConfig, config)); 9250 9251 if (localeFamilies[name]) { 9252 localeFamilies[name].forEach(function (x) { 9253 defineLocale(x.name, x.config); 9254 }); 9255 } 9256 9257 // backwards compat for now: also set the locale 9258 // make sure we set the locale AFTER all child locales have been 9259 // created, so we won't end up with the child locale set. 9260 getSetGlobalLocale(name); 9261 9262 9263 return locales[name]; 9264 } else { 9265 // useful for testing 9266 delete locales[name]; 9267 return null; 9268 } 9269 } 9270 9271 function updateLocale(name, config) { 9272 if (config != null) { 9273 var locale, tmpLocale, parentConfig = baseConfig; 9274 // MERGE 9275 tmpLocale = loadLocale(name); 9276 if (tmpLocale != null) { 9277 parentConfig = tmpLocale._config; 9278 } 9279 config = mergeConfigs(parentConfig, config); 9280 locale = new Locale(config); 9281 locale.parentLocale = locales[name]; 9282 locales[name] = locale; 9283 9284 // backwards compat for now: also set the locale 9285 getSetGlobalLocale(name); 9286 } else { 9287 // pass null for config to unupdate, useful for tests 9288 if (locales[name] != null) { 9289 if (locales[name].parentLocale != null) { 9290 locales[name] = locales[name].parentLocale; 9291 } else if (locales[name] != null) { 9292 delete locales[name]; 9293 } 9294 } 9295 } 9296 return locales[name]; 9297 } 9298 9299 // returns locale data 9300 function getLocale(key) { 9301 var locale; 9302 9303 if (key && key._locale && key._locale._abbr) { 9304 key = key._locale._abbr; 9305 } 9306 9307 if (!key) { 9308 return globalLocale; 9309 } 9310 9311 if (!isArray(key)) { 9312 //short-circuit everything else 9313 locale = loadLocale(key); 9314 if (locale) { 9315 return locale; 9316 } 9317 key = [key]; 9318 } 9319 9320 return chooseLocale(key); 9321 } 9322 9323 function listLocales() { 9324 return keys(locales); 9325 } 9326 9327 function checkOverflow(m) { 9328 var overflow; 9329 var a = m._a; 9330 9331 if (a && getParsingFlags(m).overflow === -2) { 9332 overflow = 9333 a[MONTH] < 0 || a[MONTH] > 11 ? MONTH : 9334 a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE : 9335 a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR : 9336 a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE : 9337 a[SECOND] < 0 || a[SECOND] > 59 ? SECOND : 9338 a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND : 9339 -1; 9340 9341 if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { 9342 overflow = DATE; 9343 } 9344 if (getParsingFlags(m)._overflowWeeks && overflow === -1) { 9345 overflow = WEEK; 9346 } 9347 if (getParsingFlags(m)._overflowWeekday && overflow === -1) { 9348 overflow = WEEKDAY; 9349 } 9350 9351 getParsingFlags(m).overflow = overflow; 9352 } 9353 9354 return m; 9355 } 9356 9357 // Pick the first defined of two or three arguments. 9358 function defaults(a, b, c) { 9359 if (a != null) { 9360 return a; 9361 } 9362 if (b != null) { 9363 return b; 9364 } 9365 return c; 9366 } 9367 9368 function currentDateArray(config) { 9369 // hooks is actually the exported moment object 9370 var nowValue = new Date(hooks.now()); 9371 if (config._useUTC) { 9372 return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; 9373 } 9374 return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; 9375 } 9376 9377 // convert an array to a date. 9378 // the array should mirror the parameters below 9379 // note: all values past the year are optional and will default to the lowest possible value. 9380 // [year, month, day , hour, minute, second, millisecond] 9381 function configFromArray(config) { 9382 var i, date, input = [], currentDate, expectedWeekday, yearToUse; 9383 9384 if (config._d) { 9385 return; 9386 } 9387 9388 currentDate = currentDateArray(config); 9389 9390 //compute day of the year from weeks and weekdays 9391 if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { 9392 dayOfYearFromWeekInfo(config); 9393 } 9394 9395 //if the day of the year is set, figure out what it is 9396 if (config._dayOfYear != null) { 9397 yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); 9398 9399 if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) { 9400 getParsingFlags(config)._overflowDayOfYear = true; 9401 } 9402 9403 date = createUTCDate(yearToUse, 0, config._dayOfYear); 9404 config._a[MONTH] = date.getUTCMonth(); 9405 config._a[DATE] = date.getUTCDate(); 9406 } 9407 9408 // Default to current date. 9409 // * if no year, month, day of month are given, default to today 9410 // * if day of month is given, default month and year 9411 // * if month is given, default only year 9412 // * if year is given, don't default anything 9413 for (i = 0; i < 3 && config._a[i] == null; ++i) { 9414 config._a[i] = input[i] = currentDate[i]; 9415 } 9416 9417 // Zero out whatever was not defaulted, including time 9418 for (; i < 7; i++) { 9419 config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; 9420 } 9421 9422 // Check for 24:00:00.000 9423 if (config._a[HOUR] === 24 && 9424 config._a[MINUTE] === 0 && 9425 config._a[SECOND] === 0 && 9426 config._a[MILLISECOND] === 0) { 9427 config._nextDay = true; 9428 config._a[HOUR] = 0; 9429 } 9430 9431 config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input); 9432 expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); 9433 9434 // Apply timezone offset from input. The actual utcOffset can be changed 9435 // with parseZone. 9436 if (config._tzm != null) { 9437 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); 9438 } 9439 9440 if (config._nextDay) { 9441 config._a[HOUR] = 24; 9442 } 9443 9444 // check for mismatching day of week 9445 if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) { 9446 getParsingFlags(config).weekdayMismatch = true; 9447 } 9448 } 9449 9450 function dayOfYearFromWeekInfo(config) { 9451 var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow; 9452 9453 w = config._w; 9454 if (w.GG != null || w.W != null || w.E != null) { 9455 dow = 1; 9456 doy = 4; 9457 9458 // TODO: We need to take the current isoWeekYear, but that depends on 9459 // how we interpret now (local, utc, fixed offset). So create 9460 // a now version of current config (take local/utc/offset flags, and 9461 // create now). 9462 weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year); 9463 week = defaults(w.W, 1); 9464 weekday = defaults(w.E, 1); 9465 if (weekday < 1 || weekday > 7) { 9466 weekdayOverflow = true; 9467 } 9468 } else { 9469 dow = config._locale._week.dow; 9470 doy = config._locale._week.doy; 9471 9472 var curWeek = weekOfYear(createLocal(), dow, doy); 9473 9474 weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); 9475 9476 // Default to current week. 9477 week = defaults(w.w, curWeek.week); 9478 9479 if (w.d != null) { 9480 // weekday -- low day numbers are considered next week 9481 weekday = w.d; 9482 if (weekday < 0 || weekday > 6) { 9483 weekdayOverflow = true; 9484 } 9485 } else if (w.e != null) { 9486 // local weekday -- counting starts from beginning of week 9487 weekday = w.e + dow; 9488 if (w.e < 0 || w.e > 6) { 9489 weekdayOverflow = true; 9490 } 9491 } else { 9492 // default to beginning of week 9493 weekday = dow; 9494 } 9495 } 9496 if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { 9497 getParsingFlags(config)._overflowWeeks = true; 9498 } else if (weekdayOverflow != null) { 9499 getParsingFlags(config)._overflowWeekday = true; 9500 } else { 9501 temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); 9502 config._a[YEAR] = temp.year; 9503 config._dayOfYear = temp.dayOfYear; 9504 } 9505 } 9506 9507 // iso 8601 regex 9508 // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) 9509 var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; 9510 var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; 9511 9512 var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/; 9513 9514 var isoDates = [ 9515 ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], 9516 ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/], 9517 ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/], 9518 ['GGGG-[W]WW', /\d{4}-W\d\d/, false], 9519 ['YYYY-DDD', /\d{4}-\d{3}/], 9520 ['YYYY-MM', /\d{4}-\d\d/, false], 9521 ['YYYYYYMMDD', /[+-]\d{10}/], 9522 ['YYYYMMDD', /\d{8}/], 9523 // YYYYMM is NOT allowed by the standard 9524 ['GGGG[W]WWE', /\d{4}W\d{3}/], 9525 ['GGGG[W]WW', /\d{4}W\d{2}/, false], 9526 ['YYYYDDD', /\d{7}/] 9527 ]; 9528 9529 // iso time formats and regexes 9530 var isoTimes = [ 9531 ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/], 9532 ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/], 9533 ['HH:mm:ss', /\d\d:\d\d:\d\d/], 9534 ['HH:mm', /\d\d:\d\d/], 9535 ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/], 9536 ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/], 9537 ['HHmmss', /\d\d\d\d\d\d/], 9538 ['HHmm', /\d\d\d\d/], 9539 ['HH', /\d\d/] 9540 ]; 9541 9542 var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; 9543 9544 // date from iso format 9545 function configFromISO(config) { 9546 var i, l, 9547 string = config._i, 9548 match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), 9549 allowTime, dateFormat, timeFormat, tzFormat; 9550 9551 if (match) { 9552 getParsingFlags(config).iso = true; 9553 9554 for (i = 0, l = isoDates.length; i < l; i++) { 9555 if (isoDates[i][1].exec(match[1])) { 9556 dateFormat = isoDates[i][0]; 9557 allowTime = isoDates[i][2] !== false; 9558 break; 9559 } 9560 } 9561 if (dateFormat == null) { 9562 config._isValid = false; 9563 return; 9564 } 9565 if (match[3]) { 9566 for (i = 0, l = isoTimes.length; i < l; i++) { 9567 if (isoTimes[i][1].exec(match[3])) { 9568 // match[2] should be 'T' or space 9569 timeFormat = (match[2] || ' ') + isoTimes[i][0]; 9570 break; 9571 } 9572 } 9573 if (timeFormat == null) { 9574 config._isValid = false; 9575 return; 9576 } 9577 } 9578 if (!allowTime && timeFormat != null) { 9579 config._isValid = false; 9580 return; 9581 } 9582 if (match[4]) { 9583 if (tzRegex.exec(match[4])) { 9584 tzFormat = 'Z'; 9585 } else { 9586 config._isValid = false; 9587 return; 9588 } 9589 } 9590 config._f = dateFormat + (timeFormat || '') + (tzFormat || ''); 9591 configFromStringAndFormat(config); 9592 } else { 9593 config._isValid = false; 9594 } 9595 } 9596 9597 // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3 9598 var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/; 9599 9600 function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) { 9601 var result = [ 9602 untruncateYear(yearStr), 9603 defaultLocaleMonthsShort.indexOf(monthStr), 9604 parseInt(dayStr, 10), 9605 parseInt(hourStr, 10), 9606 parseInt(minuteStr, 10) 9607 ]; 9608 9609 if (secondStr) { 9610 result.push(parseInt(secondStr, 10)); 9611 } 9612 9613 return result; 9614 } 9615 9616 function untruncateYear(yearStr) { 9617 var year = parseInt(yearStr, 10); 9618 if (year <= 49) { 9619 return 2000 + year; 9620 } else if (year <= 999) { 9621 return 1900 + year; 9622 } 9623 return year; 9624 } 9625 9626 function preprocessRFC2822(s) { 9627 // Remove comments and folding whitespace and replace multiple-spaces with a single space 9628 return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, ''); 9629 } 9630 9631 function checkWeekday(weekdayStr, parsedInput, config) { 9632 if (weekdayStr) { 9633 // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check. 9634 var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr), 9635 weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay(); 9636 if (weekdayProvided !== weekdayActual) { 9637 getParsingFlags(config).weekdayMismatch = true; 9638 config._isValid = false; 9639 return false; 9640 } 9641 } 9642 return true; 9643 } 9644 9645 var obsOffsets = { 9646 UT: 0, 9647 GMT: 0, 9648 EDT: -4 * 60, 9649 EST: -5 * 60, 9650 CDT: -5 * 60, 9651 CST: -6 * 60, 9652 MDT: -6 * 60, 9653 MST: -7 * 60, 9654 PDT: -7 * 60, 9655 PST: -8 * 60 9656 }; 9657 9658 function calculateOffset(obsOffset, militaryOffset, numOffset) { 9659 if (obsOffset) { 9660 return obsOffsets[obsOffset]; 9661 } else if (militaryOffset) { 9662 // the only allowed military tz is Z 9663 return 0; 9664 } else { 9665 var hm = parseInt(numOffset, 10); 9666 var m = hm % 100, h = (hm - m) / 100; 9667 return h * 60 + m; 9668 } 9669 } 9670 9671 // date and time from ref 2822 format 9672 function configFromRFC2822(config) { 9673 var match = rfc2822.exec(preprocessRFC2822(config._i)); 9674 if (match) { 9675 var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]); 9676 if (!checkWeekday(match[1], parsedArray, config)) { 9677 return; 9678 } 9679 9680 config._a = parsedArray; 9681 config._tzm = calculateOffset(match[8], match[9], match[10]); 9682 9683 config._d = createUTCDate.apply(null, config._a); 9684 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); 9685 9686 getParsingFlags(config).rfc2822 = true; 9687 } else { 9688 config._isValid = false; 9689 } 9690 } 9691 9692 // date from iso format or fallback 9693 function configFromString(config) { 9694 var matched = aspNetJsonRegex.exec(config._i); 9695 9696 if (matched !== null) { 9697 config._d = new Date(+matched[1]); 9698 return; 9699 } 9700 9701 configFromISO(config); 9702 if (config._isValid === false) { 9703 delete config._isValid; 9704 } else { 9705 return; 9706 } 9707 9708 configFromRFC2822(config); 9709 if (config._isValid === false) { 9710 delete config._isValid; 9711 } else { 9712 return; 9713 } 9714 9715 // Final attempt, use Input Fallback 9716 hooks.createFromInputFallback(config); 9717 } 9718 9719 hooks.createFromInputFallback = deprecate( 9720 'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' + 9721 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' + 9722 'discouraged and will be removed in an upcoming major release. Please refer to ' + 9723 'http://momentjs.com/guides/#/warnings/js-date/ for more info.', 9724 function (config) { 9725 config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); 9726 } 9727 ); 9728 9729 // constant that refers to the ISO standard 9730 hooks.ISO_8601 = function () { }; 9731 9732 // constant that refers to the RFC 2822 form 9733 hooks.RFC_2822 = function () { }; 9734 9735 // date from string and format string 9736 function configFromStringAndFormat(config) { 9737 // TODO: Move this to another part of the creation flow to prevent circular deps 9738 if (config._f === hooks.ISO_8601) { 9739 configFromISO(config); 9740 return; 9741 } 9742 if (config._f === hooks.RFC_2822) { 9743 configFromRFC2822(config); 9744 return; 9745 } 9746 config._a = []; 9747 getParsingFlags(config).empty = true; 9748 9749 // This array is used to make a Date, either with `new Date` or `Date.UTC` 9750 var string = '' + config._i, 9751 i, parsedInput, tokens, token, skipped, 9752 stringLength = string.length, 9753 totalParsedInputLength = 0; 9754 9755 tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; 9756 9757 for (i = 0; i < tokens.length; i++) { 9758 token = tokens[i]; 9759 parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; 9760 // console.log('token', token, 'parsedInput', parsedInput, 9761 // 'regex', getParseRegexForToken(token, config)); 9762 if (parsedInput) { 9763 skipped = string.substr(0, string.indexOf(parsedInput)); 9764 if (skipped.length > 0) { 9765 getParsingFlags(config).unusedInput.push(skipped); 9766 } 9767 string = string.slice(string.indexOf(parsedInput) + parsedInput.length); 9768 totalParsedInputLength += parsedInput.length; 9769 } 9770 // don't parse if it's not a known token 9771 if (formatTokenFunctions[token]) { 9772 if (parsedInput) { 9773 getParsingFlags(config).empty = false; 9774 } 9775 else { 9776 getParsingFlags(config).unusedTokens.push(token); 9777 } 9778 addTimeToArrayFromToken(token, parsedInput, config); 9779 } 9780 else if (config._strict && !parsedInput) { 9781 getParsingFlags(config).unusedTokens.push(token); 9782 } 9783 } 9784 9785 // add remaining unparsed input length to the string 9786 getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength; 9787 if (string.length > 0) { 9788 getParsingFlags(config).unusedInput.push(string); 9789 } 9790 9791 // clear _12h flag if hour is <= 12 9792 if (config._a[HOUR] <= 12 && 9793 getParsingFlags(config).bigHour === true && 9794 config._a[HOUR] > 0) { 9795 getParsingFlags(config).bigHour = undefined; 9796 } 9797 9798 getParsingFlags(config).parsedDateParts = config._a.slice(0); 9799 getParsingFlags(config).meridiem = config._meridiem; 9800 // handle meridiem 9801 config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem); 9802 9803 configFromArray(config); 9804 checkOverflow(config); 9805 } 9806 9807 9808 function meridiemFixWrap(locale, hour, meridiem) { 9809 var isPm; 9810 9811 if (meridiem == null) { 9812 // nothing to do 9813 return hour; 9814 } 9815 if (locale.meridiemHour != null) { 9816 return locale.meridiemHour(hour, meridiem); 9817 } else if (locale.isPM != null) { 9818 // Fallback 9819 isPm = locale.isPM(meridiem); 9820 if (isPm && hour < 12) { 9821 hour += 12; 9822 } 9823 if (!isPm && hour === 12) { 9824 hour = 0; 9825 } 9826 return hour; 9827 } else { 9828 // this is not supposed to happen 9829 return hour; 9830 } 9831 } 9832 9833 // date from string and array of format strings 9834 function configFromStringAndArray(config) { 9835 var tempConfig, 9836 bestMoment, 9837 9838 scoreToBeat, 9839 i, 9840 currentScore; 9841 9842 if (config._f.length === 0) { 9843 getParsingFlags(config).invalidFormat = true; 9844 config._d = new Date(NaN); 9845 return; 9846 } 9847 9848 for (i = 0; i < config._f.length; i++) { 9849 currentScore = 0; 9850 tempConfig = copyConfig({}, config); 9851 if (config._useUTC != null) { 9852 tempConfig._useUTC = config._useUTC; 9853 } 9854 tempConfig._f = config._f[i]; 9855 configFromStringAndFormat(tempConfig); 9856 9857 if (!isValid(tempConfig)) { 9858 continue; 9859 } 9860 9861 // if there is any input that was not parsed add a penalty for that format 9862 currentScore += getParsingFlags(tempConfig).charsLeftOver; 9863 9864 //or tokens 9865 currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10; 9866 9867 getParsingFlags(tempConfig).score = currentScore; 9868 9869 if (scoreToBeat == null || currentScore < scoreToBeat) { 9870 scoreToBeat = currentScore; 9871 bestMoment = tempConfig; 9872 } 9873 } 9874 9875 extend(config, bestMoment || tempConfig); 9876 } 9877 9878 function configFromObject(config) { 9879 if (config._d) { 9880 return; 9881 } 9882 9883 var i = normalizeObjectUnits(config._i); 9884 config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) { 9885 return obj && parseInt(obj, 10); 9886 }); 9887 9888 configFromArray(config); 9889 } 9890 9891 function createFromConfig(config) { 9892 var res = new Moment(checkOverflow(prepareConfig(config))); 9893 if (res._nextDay) { 9894 // Adding is smart enough around DST 9895 res.add(1, 'd'); 9896 res._nextDay = undefined; 9897 } 9898 9899 return res; 9900 } 9901 9902 function prepareConfig(config) { 9903 var input = config._i, 9904 format = config._f; 9905 9906 config._locale = config._locale || getLocale(config._l); 9907 9908 if (input === null || (format === undefined && input === '')) { 9909 return createInvalid({ nullInput: true }); 9910 } 9911 9912 if (typeof input === 'string') { 9913 config._i = input = config._locale.preparse(input); 9914 } 9915 9916 if (isMoment(input)) { 9917 return new Moment(checkOverflow(input)); 9918 } else if (isDate(input)) { 9919 config._d = input; 9920 } else if (isArray(format)) { 9921 configFromStringAndArray(config); 9922 } else if (format) { 9923 configFromStringAndFormat(config); 9924 } else { 9925 configFromInput(config); 9926 } 9927 9928 if (!isValid(config)) { 9929 config._d = null; 9930 } 9931 9932 return config; 9933 } 9934 9935 function configFromInput(config) { 9936 var input = config._i; 9937 if (isUndefined(input)) { 9938 config._d = new Date(hooks.now()); 9939 } else if (isDate(input)) { 9940 config._d = new Date(input.valueOf()); 9941 } else if (typeof input === 'string') { 9942 configFromString(config); 9943 } else if (isArray(input)) { 9944 config._a = map(input.slice(0), function (obj) { 9945 return parseInt(obj, 10); 9946 }); 9947 configFromArray(config); 9948 } else if (isObject(input)) { 9949 configFromObject(config); 9950 } else if (isNumber(input)) { 9951 // from milliseconds 9952 config._d = new Date(input); 9953 } else { 9954 hooks.createFromInputFallback(config); 9955 } 9956 } 9957 9958 function createLocalOrUTC(input, format, locale, strict, isUTC) { 9959 var c = {}; 9960 9961 if (locale === true || locale === false) { 9962 strict = locale; 9963 locale = undefined; 9964 } 9965 9966 if ((isObject(input) && isObjectEmpty(input)) || 9967 (isArray(input) && input.length === 0)) { 9968 input = undefined; 9969 } 9970 // object construction must be done this way. 9971 // https://github.com/moment/moment/issues/1423 9972 c._isAMomentObject = true; 9973 c._useUTC = c._isUTC = isUTC; 9974 c._l = locale; 9975 c._i = input; 9976 c._f = format; 9977 c._strict = strict; 9978 9979 return createFromConfig(c); 9980 } 9981 9982 function createLocal(input, format, locale, strict) { 9983 return createLocalOrUTC(input, format, locale, strict, false); 9984 } 9985 9986 var prototypeMin = deprecate( 9987 'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', 9988 function () { 9989 var other = createLocal.apply(null, arguments); 9990 if (this.isValid() && other.isValid()) { 9991 return other < this ? this : other; 9992 } else { 9993 return createInvalid(); 9994 } 9995 } 9996 ); 9997 9998 var prototypeMax = deprecate( 9999 'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', 10000 function () { 10001 var other = createLocal.apply(null, arguments); 10002 if (this.isValid() && other.isValid()) { 10003 return other > this ? this : other; 10004 } else { 10005 return createInvalid(); 10006 } 10007 } 10008 ); 10009 10010 // Pick a moment m from moments so that m[fn](other) is true for all 10011 // other. This relies on the function fn to be transitive. 10012 // 10013 // moments should either be an array of moment objects or an array, whose 10014 // first element is an array of moment objects. 10015 function pickBy(fn, moments) { 10016 var res, i; 10017 if (moments.length === 1 && isArray(moments[0])) { 10018 moments = moments[0]; 10019 } 10020 if (!moments.length) { 10021 return createLocal(); 10022 } 10023 res = moments[0]; 10024 for (i = 1; i < moments.length; ++i) { 10025 if (!moments[i].isValid() || moments[i][fn](res)) { 10026 res = moments[i]; 10027 } 10028 } 10029 return res; 10030 } 10031 10032 // TODO: Use [].sort instead? 10033 function min() { 10034 var args = [].slice.call(arguments, 0); 10035 10036 return pickBy('isBefore', args); 10037 } 10038 10039 function max() { 10040 var args = [].slice.call(arguments, 0); 10041 10042 return pickBy('isAfter', args); 10043 } 10044 10045 var now = function () { 10046 return Date.now ? Date.now() : +(new Date()); 10047 }; 10048 10049 var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond']; 10050 10051 function isDurationValid(m) { 10052 for (var key in m) { 10053 if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) { 10054 return false; 10055 } 10056 } 10057 10058 var unitHasDecimal = false; 10059 for (var i = 0; i < ordering.length; ++i) { 10060 if (m[ordering[i]]) { 10061 if (unitHasDecimal) { 10062 return false; // only allow non-integers for smallest unit 10063 } 10064 if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) { 10065 unitHasDecimal = true; 10066 } 10067 } 10068 } 10069 10070 return true; 10071 } 10072 10073 function isValid$1() { 10074 return this._isValid; 10075 } 10076 10077 function createInvalid$1() { 10078 return createDuration(NaN); 10079 } 10080 10081 function Duration(duration) { 10082 var normalizedInput = normalizeObjectUnits(duration), 10083 years = normalizedInput.year || 0, 10084 quarters = normalizedInput.quarter || 0, 10085 months = normalizedInput.month || 0, 10086 weeks = normalizedInput.week || normalizedInput.isoWeek || 0, 10087 days = normalizedInput.day || 0, 10088 hours = normalizedInput.hour || 0, 10089 minutes = normalizedInput.minute || 0, 10090 seconds = normalizedInput.second || 0, 10091 milliseconds = normalizedInput.millisecond || 0; 10092 10093 this._isValid = isDurationValid(normalizedInput); 10094 10095 // representation for dateAddRemove 10096 this._milliseconds = +milliseconds + 10097 seconds * 1e3 + // 1000 10098 minutes * 6e4 + // 1000 * 60 10099 hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978 10100 // Because of dateAddRemove treats 24 hours as different from a 10101 // day when working around DST, we need to store them separately 10102 this._days = +days + 10103 weeks * 7; 10104 // It is impossible to translate months into days without knowing 10105 // which months you are are talking about, so we have to store 10106 // it separately. 10107 this._months = +months + 10108 quarters * 3 + 10109 years * 12; 10110 10111 this._data = {}; 10112 10113 this._locale = getLocale(); 10114 10115 this._bubble(); 10116 } 10117 10118 function isDuration(obj) { 10119 return obj instanceof Duration; 10120 } 10121 10122 function absRound(number) { 10123 if (number < 0) { 10124 return Math.round(-1 * number) * -1; 10125 } else { 10126 return Math.round(number); 10127 } 10128 } 10129 10130 // FORMATTING 10131 10132 function offset(token, separator) { 10133 addFormatToken(token, 0, 0, function () { 10134 var offset = this.utcOffset(); 10135 var sign = '+'; 10136 if (offset < 0) { 10137 offset = -offset; 10138 sign = '-'; 10139 } 10140 return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2); 10141 }); 10142 } 10143 10144 offset('Z', ':'); 10145 offset('ZZ', ''); 10146 10147 // PARSING 10148 10149 addRegexToken('Z', matchShortOffset); 10150 addRegexToken('ZZ', matchShortOffset); 10151 addParseToken(['Z', 'ZZ'], function (input, array, config) { 10152 config._useUTC = true; 10153 config._tzm = offsetFromString(matchShortOffset, input); 10154 }); 10155 10156 // HELPERS 10157 10158 // timezone chunker 10159 // '+10:00' > ['10', '00'] 10160 // '-1530' > ['-15', '30'] 10161 var chunkOffset = /([\+\-]|\d\d)/gi; 10162 10163 function offsetFromString(matcher, string) { 10164 var matches = (string || '').match(matcher); 10165 10166 if (matches === null) { 10167 return null; 10168 } 10169 10170 var chunk = matches[matches.length - 1] || []; 10171 var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0]; 10172 var minutes = +(parts[1] * 60) + toInt(parts[2]); 10173 10174 return minutes === 0 ? 10175 0 : 10176 parts[0] === '+' ? minutes : -minutes; 10177 } 10178 10179 // Return a moment from input, that is local/utc/zone equivalent to model. 10180 function cloneWithOffset(input, model) { 10181 var res, diff; 10182 if (model._isUTC) { 10183 res = model.clone(); 10184 diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); 10185 // Use low-level api, because this fn is low-level api. 10186 res._d.setTime(res._d.valueOf() + diff); 10187 hooks.updateOffset(res, false); 10188 return res; 10189 } else { 10190 return createLocal(input).local(); 10191 } 10192 } 10193 10194 function getDateOffset(m) { 10195 // On Firefox.24 Date#getTimezoneOffset returns a floating point. 10196 // https://github.com/moment/moment/pull/1871 10197 return -Math.round(m._d.getTimezoneOffset() / 15) * 15; 10198 } 10199 10200 // HOOKS 10201 10202 // This function will be called whenever a moment is mutated. 10203 // It is intended to keep the offset in sync with the timezone. 10204 hooks.updateOffset = function () { }; 10205 10206 // MOMENTS 10207 10208 // keepLocalTime = true means only change the timezone, without 10209 // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--> 10210 // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset 10211 // +0200, so we adjust the time as needed, to be valid. 10212 // 10213 // Keeping the time actually adds/subtracts (one hour) 10214 // from the actual represented time. That is why we call updateOffset 10215 // a second time. In case it wants us to change the offset again 10216 // _changeInProgress == true case, then we have to adjust, because 10217 // there is no such time in the given timezone. 10218 function getSetOffset(input, keepLocalTime, keepMinutes) { 10219 var offset = this._offset || 0, 10220 localAdjust; 10221 if (!this.isValid()) { 10222 return input != null ? this : NaN; 10223 } 10224 if (input != null) { 10225 if (typeof input === 'string') { 10226 input = offsetFromString(matchShortOffset, input); 10227 if (input === null) { 10228 return this; 10229 } 10230 } else if (Math.abs(input) < 16 && !keepMinutes) { 10231 input = input * 60; 10232 } 10233 if (!this._isUTC && keepLocalTime) { 10234 localAdjust = getDateOffset(this); 10235 } 10236 this._offset = input; 10237 this._isUTC = true; 10238 if (localAdjust != null) { 10239 this.add(localAdjust, 'm'); 10240 } 10241 if (offset !== input) { 10242 if (!keepLocalTime || this._changeInProgress) { 10243 addSubtract(this, createDuration(input - offset, 'm'), 1, false); 10244 } else if (!this._changeInProgress) { 10245 this._changeInProgress = true; 10246 hooks.updateOffset(this, true); 10247 this._changeInProgress = null; 10248 } 10249 } 10250 return this; 10251 } else { 10252 return this._isUTC ? offset : getDateOffset(this); 10253 } 10254 } 10255 10256 function getSetZone(input, keepLocalTime) { 10257 if (input != null) { 10258 if (typeof input !== 'string') { 10259 input = -input; 10260 } 10261 10262 this.utcOffset(input, keepLocalTime); 10263 10264 return this; 10265 } else { 10266 return -this.utcOffset(); 10267 } 10268 } 10269 10270 function setOffsetToUTC(keepLocalTime) { 10271 return this.utcOffset(0, keepLocalTime); 10272 } 10273 10274 function setOffsetToLocal(keepLocalTime) { 10275 if (this._isUTC) { 10276 this.utcOffset(0, keepLocalTime); 10277 this._isUTC = false; 10278 10279 if (keepLocalTime) { 10280 this.subtract(getDateOffset(this), 'm'); 10281 } 10282 } 10283 return this; 10284 } 10285 10286 function setOffsetToParsedOffset() { 10287 if (this._tzm != null) { 10288 this.utcOffset(this._tzm, false, true); 10289 } else if (typeof this._i === 'string') { 10290 var tZone = offsetFromString(matchOffset, this._i); 10291 if (tZone != null) { 10292 this.utcOffset(tZone); 10293 } 10294 else { 10295 this.utcOffset(0, true); 10296 } 10297 } 10298 return this; 10299 } 10300 10301 function hasAlignedHourOffset(input) { 10302 if (!this.isValid()) { 10303 return false; 10304 } 10305 input = input ? createLocal(input).utcOffset() : 0; 10306 10307 return (this.utcOffset() - input) % 60 === 0; 10308 } 10309 10310 function isDaylightSavingTime() { 10311 return ( 10312 this.utcOffset() > this.clone().month(0).utcOffset() || 10313 this.utcOffset() > this.clone().month(5).utcOffset() 10314 ); 10315 } 10316 10317 function isDaylightSavingTimeShifted() { 10318 if (!isUndefined(this._isDSTShifted)) { 10319 return this._isDSTShifted; 10320 } 10321 10322 var c = {}; 10323 10324 copyConfig(c, this); 10325 c = prepareConfig(c); 10326 10327 if (c._a) { 10328 var other = c._isUTC ? createUTC(c._a) : createLocal(c._a); 10329 this._isDSTShifted = this.isValid() && 10330 compareArrays(c._a, other.toArray()) > 0; 10331 } else { 10332 this._isDSTShifted = false; 10333 } 10334 10335 return this._isDSTShifted; 10336 } 10337 10338 function isLocal() { 10339 return this.isValid() ? !this._isUTC : false; 10340 } 10341 10342 function isUtcOffset() { 10343 return this.isValid() ? this._isUTC : false; 10344 } 10345 10346 function isUtc() { 10347 return this.isValid() ? this._isUTC && this._offset === 0 : false; 10348 } 10349 10350 // ASP.NET json date format regex 10351 var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; 10352 10353 // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html 10354 // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere 10355 // and further modified to allow for strings containing both week and day 10356 var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; 10357 10358 function createDuration(input, key) { 10359 var duration = input, 10360 // matching against regexp is expensive, do it on demand 10361 match = null, 10362 sign, 10363 ret, 10364 diffRes; 10365 10366 if (isDuration(input)) { 10367 duration = { 10368 ms: input._milliseconds, 10369 d: input._days, 10370 M: input._months 10371 }; 10372 } else if (isNumber(input)) { 10373 duration = {}; 10374 if (key) { 10375 duration[key] = input; 10376 } else { 10377 duration.milliseconds = input; 10378 } 10379 } else if (!!(match = aspNetRegex.exec(input))) { 10380 sign = (match[1] === '-') ? -1 : 1; 10381 duration = { 10382 y: 0, 10383 d: toInt(match[DATE]) * sign, 10384 h: toInt(match[HOUR]) * sign, 10385 m: toInt(match[MINUTE]) * sign, 10386 s: toInt(match[SECOND]) * sign, 10387 ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match 10388 }; 10389 } else if (!!(match = isoRegex.exec(input))) { 10390 sign = (match[1] === '-') ? -1 : 1; 10391 duration = { 10392 y: parseIso(match[2], sign), 10393 M: parseIso(match[3], sign), 10394 w: parseIso(match[4], sign), 10395 d: parseIso(match[5], sign), 10396 h: parseIso(match[6], sign), 10397 m: parseIso(match[7], sign), 10398 s: parseIso(match[8], sign) 10399 }; 10400 } else if (duration == null) {// checks for null or undefined 10401 duration = {}; 10402 } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) { 10403 diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to)); 10404 10405 duration = {}; 10406 duration.ms = diffRes.milliseconds; 10407 duration.M = diffRes.months; 10408 } 10409 10410 ret = new Duration(duration); 10411 10412 if (isDuration(input) && hasOwnProp(input, '_locale')) { 10413 ret._locale = input._locale; 10414 } 10415 10416 return ret; 10417 } 10418 10419 createDuration.fn = Duration.prototype; 10420 createDuration.invalid = createInvalid$1; 10421 10422 function parseIso(inp, sign) { 10423 // We'd normally use ~~inp for this, but unfortunately it also 10424 // converts floats to ints. 10425 // inp may be undefined, so careful calling replace on it. 10426 var res = inp && parseFloat(inp.replace(',', '.')); 10427 // apply sign while we're at it 10428 return (isNaN(res) ? 0 : res) * sign; 10429 } 10430 10431 function positiveMomentsDifference(base, other) { 10432 var res = {}; 10433 10434 res.months = other.month() - base.month() + 10435 (other.year() - base.year()) * 12; 10436 if (base.clone().add(res.months, 'M').isAfter(other)) { 10437 --res.months; 10438 } 10439 10440 res.milliseconds = +other - +(base.clone().add(res.months, 'M')); 10441 10442 return res; 10443 } 10444 10445 function momentsDifference(base, other) { 10446 var res; 10447 if (!(base.isValid() && other.isValid())) { 10448 return { milliseconds: 0, months: 0 }; 10449 } 10450 10451 other = cloneWithOffset(other, base); 10452 if (base.isBefore(other)) { 10453 res = positiveMomentsDifference(base, other); 10454 } else { 10455 res = positiveMomentsDifference(other, base); 10456 res.milliseconds = -res.milliseconds; 10457 res.months = -res.months; 10458 } 10459 10460 return res; 10461 } 10462 10463 // TODO: remove 'name' arg after deprecation is removed 10464 function createAdder(direction, name) { 10465 return function (val, period) { 10466 var dur, tmp; 10467 //invert the arguments, but complain about it 10468 if (period !== null && !isNaN(+period)) { 10469 deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' + 10470 'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'); 10471 tmp = val; val = period; period = tmp; 10472 } 10473 10474 val = typeof val === 'string' ? +val : val; 10475 dur = createDuration(val, period); 10476 addSubtract(this, dur, direction); 10477 return this; 10478 }; 10479 } 10480 10481 function addSubtract(mom, duration, isAdding, updateOffset) { 10482 var milliseconds = duration._milliseconds, 10483 days = absRound(duration._days), 10484 months = absRound(duration._months); 10485 10486 if (!mom.isValid()) { 10487 // No op 10488 return; 10489 } 10490 10491 updateOffset = updateOffset == null ? true : updateOffset; 10492 10493 if (months) { 10494 setMonth(mom, get(mom, 'Month') + months * isAdding); 10495 } 10496 if (days) { 10497 set$1(mom, 'Date', get(mom, 'Date') + days * isAdding); 10498 } 10499 if (milliseconds) { 10500 mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding); 10501 } 10502 if (updateOffset) { 10503 hooks.updateOffset(mom, days || months); 10504 } 10505 } 10506 10507 var add = createAdder(1, 'add'); 10508 var subtract = createAdder(-1, 'subtract'); 10509 10510 function getCalendarFormat(myMoment, now) { 10511 var diff = myMoment.diff(now, 'days', true); 10512 return diff < -6 ? 'sameElse' : 10513 diff < -1 ? 'lastWeek' : 10514 diff < 0 ? 'lastDay' : 10515 diff < 1 ? 'sameDay' : 10516 diff < 2 ? 'nextDay' : 10517 diff < 7 ? 'nextWeek' : 'sameElse'; 10518 } 10519 10520 function calendar$1(time, formats) { 10521 // We want to compare the start of today, vs this. 10522 // Getting start-of-today depends on whether we're local/utc/offset or not. 10523 var now = time || createLocal(), 10524 sod = cloneWithOffset(now, this).startOf('day'), 10525 format = hooks.calendarFormat(this, sod) || 'sameElse'; 10526 10527 var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]); 10528 10529 return this.format(output || this.localeData().calendar(format, this, createLocal(now))); 10530 } 10531 10532 function clone() { 10533 return new Moment(this); 10534 } 10535 10536 function isAfter(input, units) { 10537 var localInput = isMoment(input) ? input : createLocal(input); 10538 if (!(this.isValid() && localInput.isValid())) { 10539 return false; 10540 } 10541 units = normalizeUnits(units) || 'millisecond'; 10542 if (units === 'millisecond') { 10543 return this.valueOf() > localInput.valueOf(); 10544 } else { 10545 return localInput.valueOf() < this.clone().startOf(units).valueOf(); 10546 } 10547 } 10548 10549 function isBefore(input, units) { 10550 var localInput = isMoment(input) ? input : createLocal(input); 10551 if (!(this.isValid() && localInput.isValid())) { 10552 return false; 10553 } 10554 units = normalizeUnits(units) || 'millisecond'; 10555 if (units === 'millisecond') { 10556 return this.valueOf() < localInput.valueOf(); 10557 } else { 10558 return this.clone().endOf(units).valueOf() < localInput.valueOf(); 10559 } 10560 } 10561 10562 function isBetween(from, to, units, inclusivity) { 10563 var localFrom = isMoment(from) ? from : createLocal(from), 10564 localTo = isMoment(to) ? to : createLocal(to); 10565 if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) { 10566 return false; 10567 } 10568 inclusivity = inclusivity || '()'; 10569 return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) && 10570 (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units)); 10571 } 10572 10573 function isSame(input, units) { 10574 var localInput = isMoment(input) ? input : createLocal(input), 10575 inputMs; 10576 if (!(this.isValid() && localInput.isValid())) { 10577 return false; 10578 } 10579 units = normalizeUnits(units) || 'millisecond'; 10580 if (units === 'millisecond') { 10581 return this.valueOf() === localInput.valueOf(); 10582 } else { 10583 inputMs = localInput.valueOf(); 10584 return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf(); 10585 } 10586 } 10587 10588 function isSameOrAfter(input, units) { 10589 return this.isSame(input, units) || this.isAfter(input, units); 10590 } 10591 10592 function isSameOrBefore(input, units) { 10593 return this.isSame(input, units) || this.isBefore(input, units); 10594 } 10595 10596 function diff(input, units, asFloat) { 10597 var that, 10598 zoneDelta, 10599 output; 10600 10601 if (!this.isValid()) { 10602 return NaN; 10603 } 10604 10605 that = cloneWithOffset(input, this); 10606 10607 if (!that.isValid()) { 10608 return NaN; 10609 } 10610 10611 zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4; 10612 10613 units = normalizeUnits(units); 10614 10615 switch (units) { 10616 case 'year': output = monthDiff(this, that) / 12; break; 10617 case 'month': output = monthDiff(this, that); break; 10618 case 'quarter': output = monthDiff(this, that) / 3; break; 10619 case 'second': output = (this - that) / 1e3; break; // 1000 10620 case 'minute': output = (this - that) / 6e4; break; // 1000 * 60 10621 case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60 10622 case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst 10623 case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst 10624 default: output = this - that; 10625 } 10626 10627 return asFloat ? output : absFloor(output); 10628 } 10629 10630 function monthDiff(a, b) { 10631 // difference in months 10632 var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()), 10633 // b is in (anchor - 1 month, anchor + 1 month) 10634 anchor = a.clone().add(wholeMonthDiff, 'months'), 10635 anchor2, adjust; 10636 10637 if (b - anchor < 0) { 10638 anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); 10639 // linear across the month 10640 adjust = (b - anchor) / (anchor - anchor2); 10641 } else { 10642 anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); 10643 // linear across the month 10644 adjust = (b - anchor) / (anchor2 - anchor); 10645 } 10646 10647 //check for negative zero, return zero if negative zero 10648 return -(wholeMonthDiff + adjust) || 0; 10649 } 10650 10651 hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ'; 10652 hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]'; 10653 10654 function toString() { 10655 return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); 10656 } 10657 10658 function toISOString(keepOffset) { 10659 if (!this.isValid()) { 10660 return null; 10661 } 10662 var utc = keepOffset !== true; 10663 var m = utc ? this.clone().utc() : this; 10664 if (m.year() < 0 || m.year() > 9999) { 10665 return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'); 10666 } 10667 if (isFunction(Date.prototype.toISOString)) { 10668 // native implementation is ~50x faster, use it when we can 10669 if (utc) { 10670 return this.toDate().toISOString(); 10671 } else { 10672 return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z')); 10673 } 10674 } 10675 return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'); 10676 } 10677 10678 /** 10679 * Return a human readable representation of a moment that can 10680 * also be evaluated to get a new moment which is the same 10681 * 10682 * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects 10683 */ 10684 function inspect() { 10685 if (!this.isValid()) { 10686 return 'moment.invalid(/* ' + this._i + ' */)'; 10687 } 10688 var func = 'moment'; 10689 var zone = ''; 10690 if (!this.isLocal()) { 10691 func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone'; 10692 zone = 'Z'; 10693 } 10694 var prefix = '[' + func + '("]'; 10695 var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY'; 10696 var datetime = '-MM-DD[T]HH:mm:ss.SSS'; 10697 var suffix = zone + '[")]'; 10698 10699 return this.format(prefix + year + datetime + suffix); 10700 } 10701 10702 function format(inputString) { 10703 if (!inputString) { 10704 inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat; 10705 } 10706 var output = formatMoment(this, inputString); 10707 return this.localeData().postformat(output); 10708 } 10709 10710 function from(time, withoutSuffix) { 10711 if (this.isValid() && 10712 ((isMoment(time) && time.isValid()) || 10713 createLocal(time).isValid())) { 10714 return createDuration({ to: this, from: time }).locale(this.locale()).humanize(!withoutSuffix); 10715 } else { 10716 return this.localeData().invalidDate(); 10717 } 10718 } 10719 10720 function fromNow(withoutSuffix) { 10721 return this.from(createLocal(), withoutSuffix); 10722 } 10723 10724 function to(time, withoutSuffix) { 10725 if (this.isValid() && 10726 ((isMoment(time) && time.isValid()) || 10727 createLocal(time).isValid())) { 10728 return createDuration({ from: this, to: time }).locale(this.locale()).humanize(!withoutSuffix); 10729 } else { 10730 return this.localeData().invalidDate(); 10731 } 10732 } 10733 10734 function toNow(withoutSuffix) { 10735 return this.to(createLocal(), withoutSuffix); 10736 } 10737 10738 // If passed a locale key, it will set the locale for this 10739 // instance. Otherwise, it will return the locale configuration 10740 // variables for this instance. 10741 function locale(key) { 10742 var newLocaleData; 10743 10744 if (key === undefined) { 10745 return this._locale._abbr; 10746 } else { 10747 newLocaleData = getLocale(key); 10748 if (newLocaleData != null) { 10749 this._locale = newLocaleData; 10750 } 10751 return this; 10752 } 10753 } 10754 10755 var lang = deprecate( 10756 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', 10757 function (key) { 10758 if (key === undefined) { 10759 return this.localeData(); 10760 } else { 10761 return this.locale(key); 10762 } 10763 } 10764 ); 10765 10766 function localeData() { 10767 return this._locale; 10768 } 10769 10770 var MS_PER_SECOND = 1000; 10771 var MS_PER_MINUTE = 60 * MS_PER_SECOND; 10772 var MS_PER_HOUR = 60 * MS_PER_MINUTE; 10773 var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR; 10774 10775 // actual modulo - handles negative numbers (for dates before 1970): 10776 function mod$1(dividend, divisor) { 10777 return (dividend % divisor + divisor) % divisor; 10778 } 10779 10780 function localStartOfDate(y, m, d) { 10781 // the date constructor remaps years 0-99 to 1900-1999 10782 if (y < 100 && y >= 0) { 10783 // preserve leap years using a full 400 year cycle, then reset 10784 return new Date(y + 400, m, d) - MS_PER_400_YEARS; 10785 } else { 10786 return new Date(y, m, d).valueOf(); 10787 } 10788 } 10789 10790 function utcStartOfDate(y, m, d) { 10791 // Date.UTC remaps years 0-99 to 1900-1999 10792 if (y < 100 && y >= 0) { 10793 // preserve leap years using a full 400 year cycle, then reset 10794 return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS; 10795 } else { 10796 return Date.UTC(y, m, d); 10797 } 10798 } 10799 10800 function startOf(units) { 10801 var time; 10802 units = normalizeUnits(units); 10803 if (units === undefined || units === 'millisecond' || !this.isValid()) { 10804 return this; 10805 } 10806 10807 var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; 10808 10809 switch (units) { 10810 case 'year': 10811 time = startOfDate(this.year(), 0, 1); 10812 break; 10813 case 'quarter': 10814 time = startOfDate(this.year(), this.month() - this.month() % 3, 1); 10815 break; 10816 case 'month': 10817 time = startOfDate(this.year(), this.month(), 1); 10818 break; 10819 case 'week': 10820 time = startOfDate(this.year(), this.month(), this.date() - this.weekday()); 10821 break; 10822 case 'isoWeek': 10823 time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1)); 10824 break; 10825 case 'day': 10826 case 'date': 10827 time = startOfDate(this.year(), this.month(), this.date()); 10828 break; 10829 case 'hour': 10830 time = this._d.valueOf(); 10831 time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR); 10832 break; 10833 case 'minute': 10834 time = this._d.valueOf(); 10835 time -= mod$1(time, MS_PER_MINUTE); 10836 break; 10837 case 'second': 10838 time = this._d.valueOf(); 10839 time -= mod$1(time, MS_PER_SECOND); 10840 break; 10841 } 10842 10843 this._d.setTime(time); 10844 hooks.updateOffset(this, true); 10845 return this; 10846 } 10847 10848 function endOf(units) { 10849 var time; 10850 units = normalizeUnits(units); 10851 if (units === undefined || units === 'millisecond' || !this.isValid()) { 10852 return this; 10853 } 10854 10855 var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; 10856 10857 switch (units) { 10858 case 'year': 10859 time = startOfDate(this.year() + 1, 0, 1) - 1; 10860 break; 10861 case 'quarter': 10862 time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1; 10863 break; 10864 case 'month': 10865 time = startOfDate(this.year(), this.month() + 1, 1) - 1; 10866 break; 10867 case 'week': 10868 time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1; 10869 break; 10870 case 'isoWeek': 10871 time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1; 10872 break; 10873 case 'day': 10874 case 'date': 10875 time = startOfDate(this.year(), this.month(), this.date() + 1) - 1; 10876 break; 10877 case 'hour': 10878 time = this._d.valueOf(); 10879 time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1; 10880 break; 10881 case 'minute': 10882 time = this._d.valueOf(); 10883 time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1; 10884 break; 10885 case 'second': 10886 time = this._d.valueOf(); 10887 time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1; 10888 break; 10889 } 10890 10891 this._d.setTime(time); 10892 hooks.updateOffset(this, true); 10893 return this; 10894 } 10895 10896 function valueOf() { 10897 return this._d.valueOf() - ((this._offset || 0) * 60000); 10898 } 10899 10900 function unix() { 10901 return Math.floor(this.valueOf() / 1000); 10902 } 10903 10904 function toDate() { 10905 return new Date(this.valueOf()); 10906 } 10907 10908 function toArray() { 10909 var m = this; 10910 return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()]; 10911 } 10912 10913 function toObject() { 10914 var m = this; 10915 return { 10916 years: m.year(), 10917 months: m.month(), 10918 date: m.date(), 10919 hours: m.hours(), 10920 minutes: m.minutes(), 10921 seconds: m.seconds(), 10922 milliseconds: m.milliseconds() 10923 }; 10924 } 10925 10926 function toJSON() { 10927 // new Date(NaN).toJSON() === null 10928 return this.isValid() ? this.toISOString() : null; 10929 } 10930 10931 function isValid$2() { 10932 return isValid(this); 10933 } 10934 10935 function parsingFlags() { 10936 return extend({}, getParsingFlags(this)); 10937 } 10938 10939 function invalidAt() { 10940 return getParsingFlags(this).overflow; 10941 } 10942 10943 function creationData() { 10944 return { 10945 input: this._i, 10946 format: this._f, 10947 locale: this._locale, 10948 isUTC: this._isUTC, 10949 strict: this._strict 10950 }; 10951 } 10952 10953 // FORMATTING 10954 10955 addFormatToken(0, ['gg', 2], 0, function () { 10956 return this.weekYear() % 100; 10957 }); 10958 10959 addFormatToken(0, ['GG', 2], 0, function () { 10960 return this.isoWeekYear() % 100; 10961 }); 10962 10963 function addWeekYearFormatToken(token, getter) { 10964 addFormatToken(0, [token, token.length], 0, getter); 10965 } 10966 10967 addWeekYearFormatToken('gggg', 'weekYear'); 10968 addWeekYearFormatToken('ggggg', 'weekYear'); 10969 addWeekYearFormatToken('GGGG', 'isoWeekYear'); 10970 addWeekYearFormatToken('GGGGG', 'isoWeekYear'); 10971 10972 // ALIASES 10973 10974 addUnitAlias('weekYear', 'gg'); 10975 addUnitAlias('isoWeekYear', 'GG'); 10976 10977 // PRIORITY 10978 10979 addUnitPriority('weekYear', 1); 10980 addUnitPriority('isoWeekYear', 1); 10981 10982 10983 // PARSING 10984 10985 addRegexToken('G', matchSigned); 10986 addRegexToken('g', matchSigned); 10987 addRegexToken('GG', match1to2, match2); 10988 addRegexToken('gg', match1to2, match2); 10989 addRegexToken('GGGG', match1to4, match4); 10990 addRegexToken('gggg', match1to4, match4); 10991 addRegexToken('GGGGG', match1to6, match6); 10992 addRegexToken('ggggg', match1to6, match6); 10993
vendor: 2,070 bytes, lines 10994-11064
10994 addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) { 10995 week[token.substr(0, 2)] = toInt(input); 10996 }); 10997 10998 addWeekParseToken(['gg', 'GG'], function (input, week, config, token) { 10999 week[token] = hooks.parseTwoDigitYear(input); 11000 }); 11001 11002 // MOMENTS 11003 11004 function getSetWeekYear(input) { 11005 return getSetWeekYearHelper.call(this, 11006 input, 11007 this.week(), 11008 this.weekday(), 11009 this.localeData()._week.dow, 11010 this.localeData()._week.doy); 11011 } 11012 11013 function getSetISOWeekYear(input) { 11014 return getSetWeekYearHelper.call(this, 11015 input, this.isoWeek(), this.isoWeekday(), 1, 4); 11016 } 11017 11018 function getISOWeeksInYear() { 11019 return weeksInYear(this.year(), 1, 4); 11020 } 11021 11022 function getWeeksInYear() { 11023 var weekInfo = this.localeData()._week; 11024 return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); 11025 } 11026 11027 function getSetWeekYearHelper(input, week, weekday, dow, doy) { 11028 var weeksTarget; 11029 if (input == null) { 11030 return weekOfYear(this, dow, doy).year; 11031 } else { 11032 weeksTarget = weeksInYear(input, dow, doy); 11033 if (week > weeksTarget) { 11034 week = weeksTarget; 11035 } 11036 return setWeekAll.call(this, input, week, weekday, dow, doy); 11037 } 11038 } 11039 11040 function setWeekAll(weekYear, week, weekday, dow, doy) { 11041 var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy), 11042 date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear); 11043 11044 this.year(date.getUTCFullYear()); 11045 this.month(date.getUTCMonth()); 11046 this.date(date.getUTCDate()); 11047 return this; 11048 } 11049 11050 // FORMATTING 11051 11052 addFormatToken('Q', 0, 'Qo', 'quarter'); 11053 11054 // ALIASES 11055 11056 addUnitAlias('quarter', 'Q'); 11057 11058 // PRIORITY 11059 11060 addUnitPriority('quarter', 7); 11061 11062 // PARSING 11063 11064 addRegexToken('Q', match1);
vendor: 25,016 bytes, lines 11065-11874
11065 addParseToken('Q', function (input, array) { 11066 array[MONTH] = (toInt(input) - 1) * 3; 11067 }); 11068 11069 // MOMENTS 11070 11071 function getSetQuarter(input) { 11072 return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); 11073 } 11074 11075 // FORMATTING 11076 11077 addFormatToken('D', ['DD', 2], 'Do', 'date'); 11078 11079 // ALIASES 11080 11081 addUnitAlias('date', 'D'); 11082 11083 // PRIORITY 11084 addUnitPriority('date', 9); 11085 11086 // PARSING 11087 11088 addRegexToken('D', match1to2); 11089 addRegexToken('DD', match1to2, match2); 11090 addRegexToken('Do', function (isStrict, locale) { 11091 // TODO: Remove "ordinalParse" fallback in next major release. 11092 return isStrict ? 11093 (locale._dayOfMonthOrdinalParse || locale._ordinalParse) : 11094 locale._dayOfMonthOrdinalParseLenient; 11095 }); 11096 11097 addParseToken(['D', 'DD'], DATE); 11098 addParseToken('Do', function (input, array) { 11099 array[DATE] = toInt(input.match(match1to2)[0]); 11100 }); 11101 11102 // MOMENTS 11103 11104 var getSetDayOfMonth = makeGetSet('Date', true); 11105 11106 // FORMATTING 11107 11108 addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); 11109 11110 // ALIASES 11111 11112 addUnitAlias('dayOfYear', 'DDD'); 11113 11114 // PRIORITY 11115 addUnitPriority('dayOfYear', 4); 11116 11117 // PARSING 11118 11119 addRegexToken('DDD', match1to3); 11120 addRegexToken('DDDD', match3); 11121 addParseToken(['DDD', 'DDDD'], function (input, array, config) { 11122 config._dayOfYear = toInt(input); 11123 }); 11124 11125 // HELPERS 11126 11127 // MOMENTS 11128 11129 function getSetDayOfYear(input) { 11130 var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1; 11131 return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); 11132 } 11133 11134 // FORMATTING 11135 11136 addFormatToken('m', ['mm', 2], 0, 'minute'); 11137 11138 // ALIASES 11139 11140 addUnitAlias('minute', 'm'); 11141 11142 // PRIORITY 11143 11144 addUnitPriority('minute', 14); 11145 11146 // PARSING 11147 11148 addRegexToken('m', match1to2); 11149 addRegexToken('mm', match1to2, match2); 11150 addParseToken(['m', 'mm'], MINUTE); 11151 11152 // MOMENTS 11153 11154 var getSetMinute = makeGetSet('Minutes', false); 11155 11156 // FORMATTING 11157 11158 addFormatToken('s', ['ss', 2], 0, 'second'); 11159 11160 // ALIASES 11161 11162 addUnitAlias('second', 's'); 11163 11164 // PRIORITY 11165 11166 addUnitPriority('second', 15); 11167 11168 // PARSING 11169 11170 addRegexToken('s', match1to2); 11171 addRegexToken('ss', match1to2, match2); 11172 addParseToken(['s', 'ss'], SECOND); 11173 11174 // MOMENTS 11175 11176 var getSetSecond = makeGetSet('Seconds', false); 11177 11178 // FORMATTING 11179 11180 addFormatToken('S', 0, 0, function () { 11181 return ~~(this.millisecond() / 100); 11182 }); 11183 11184 addFormatToken(0, ['SS', 2], 0, function () { 11185 return ~~(this.millisecond() / 10); 11186 }); 11187 11188 addFormatToken(0, ['SSS', 3], 0, 'millisecond'); 11189 addFormatToken(0, ['SSSS', 4], 0, function () { 11190 return this.millisecond() * 10; 11191 }); 11192 addFormatToken(0, ['SSSSS', 5], 0, function () { 11193 return this.millisecond() * 100; 11194 }); 11195 addFormatToken(0, ['SSSSSS', 6], 0, function () { 11196 return this.millisecond() * 1000; 11197 }); 11198 addFormatToken(0, ['SSSSSSS', 7], 0, function () { 11199 return this.millisecond() * 10000; 11200 }); 11201 addFormatToken(0, ['SSSSSSSS', 8], 0, function () { 11202 return this.millisecond() * 100000; 11203 }); 11204 addFormatToken(0, ['SSSSSSSSS', 9], 0, function () { 11205 return this.millisecond() * 1000000; 11206 }); 11207 11208 11209 // ALIASES 11210 11211 addUnitAlias('millisecond', 'ms'); 11212 11213 // PRIORITY 11214 11215 addUnitPriority('millisecond', 16); 11216 11217 // PARSING 11218 11219 addRegexToken('S', match1to3, match1); 11220 addRegexToken('SS', match1to3, match2); 11221 addRegexToken('SSS', match1to3, match3); 11222 11223 var token; 11224 for (token = 'SSSS'; token.length <= 9; token += 'S') { 11225 addRegexToken(token, matchUnsigned); 11226 } 11227 11228 function parseMs(input, array) { 11229 array[MILLISECOND] = toInt(('0.' + input) * 1000); 11230 } 11231 11232 for (token = 'S'; token.length <= 9; token += 'S') { 11233 addParseToken(token, parseMs); 11234 } 11235 // MOMENTS 11236 11237 var getSetMillisecond = makeGetSet('Milliseconds', false); 11238 11239 // FORMATTING 11240 11241 addFormatToken('z', 0, 0, 'zoneAbbr'); 11242 addFormatToken('zz', 0, 0, 'zoneName'); 11243 11244 // MOMENTS 11245 11246 function getZoneAbbr() { 11247 return this._isUTC ? 'UTC' : ''; 11248 } 11249 11250 function getZoneName() { 11251 return this._isUTC ? 'Coordinated Universal Time' : ''; 11252 } 11253 11254 var proto = Moment.prototype; 11255 11256 proto.add = add; 11257 proto.calendar = calendar$1; 11258 proto.clone = clone; 11259 proto.diff = diff; 11260 proto.endOf = endOf; 11261 proto.format = format; 11262 proto.from = from; 11263 proto.fromNow = fromNow; 11264 proto.to = to; 11265 proto.toNow = toNow; 11266 proto.get = stringGet; 11267 proto.invalidAt = invalidAt; 11268 proto.isAfter = isAfter; 11269 proto.isBefore = isBefore; 11270 proto.isBetween = isBetween; 11271 proto.isSame = isSame; 11272 proto.isSameOrAfter = isSameOrAfter; 11273 proto.isSameOrBefore = isSameOrBefore; 11274 proto.isValid = isValid$2; 11275 proto.lang = lang; 11276 proto.locale = locale; 11277 proto.localeData = localeData; 11278 proto.max = prototypeMax; 11279 proto.min = prototypeMin; 11280 proto.parsingFlags = parsingFlags; 11281 proto.set = stringSet; 11282 proto.startOf = startOf; 11283 proto.subtract = subtract; 11284 proto.toArray = toArray; 11285 proto.toObject = toObject; 11286 proto.toDate = toDate; 11287 proto.toISOString = toISOString; 11288 proto.inspect = inspect; 11289 proto.toJSON = toJSON; 11290 proto.toString = toString; 11291 proto.unix = unix; 11292 proto.valueOf = valueOf; 11293 proto.creationData = creationData; 11294 proto.year = getSetYear; 11295 proto.isLeapYear = getIsLeapYear; 11296 proto.weekYear = getSetWeekYear; 11297 proto.isoWeekYear = getSetISOWeekYear; 11298 proto.quarter = proto.quarters = getSetQuarter; 11299 proto.month = getSetMonth; 11300 proto.daysInMonth = getDaysInMonth; 11301 proto.week = proto.weeks = getSetWeek; 11302 proto.isoWeek = proto.isoWeeks = getSetISOWeek; 11303 proto.weeksInYear = getWeeksInYear; 11304 proto.isoWeeksInYear = getISOWeeksInYear; 11305 proto.date = getSetDayOfMonth; 11306 proto.day = proto.days = getSetDayOfWeek; 11307 proto.weekday = getSetLocaleDayOfWeek; 11308 proto.isoWeekday = getSetISODayOfWeek; 11309 proto.dayOfYear = getSetDayOfYear; 11310 proto.hour = proto.hours = getSetHour; 11311 proto.minute = proto.minutes = getSetMinute; 11312 proto.second = proto.seconds = getSetSecond; 11313 proto.millisecond = proto.milliseconds = getSetMillisecond; 11314 proto.utcOffset = getSetOffset; 11315 proto.utc = setOffsetToUTC; 11316 proto.local = setOffsetToLocal; 11317 proto.parseZone = setOffsetToParsedOffset; 11318 proto.hasAlignedHourOffset = hasAlignedHourOffset; 11319 proto.isDST = isDaylightSavingTime; 11320 proto.isLocal = isLocal; 11321 proto.isUtcOffset = isUtcOffset; 11322 proto.isUtc = isUtc; 11323 proto.isUTC = isUtc; 11324 proto.zoneAbbr = getZoneAbbr; 11325 proto.zoneName = getZoneName; 11326 proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth); 11327 proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth); 11328 proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear); 11329 proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone); 11330 proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted); 11331 11332 function createUnix(input) { 11333 return createLocal(input * 1000); 11334 } 11335 11336 function createInZone() { 11337 return createLocal.apply(null, arguments).parseZone(); 11338 } 11339 11340 function preParsePostFormat(string) { 11341 return string; 11342 } 11343 11344 var proto$1 = Locale.prototype; 11345 11346 proto$1.calendar = calendar; 11347 proto$1.longDateFormat = longDateFormat; 11348 proto$1.invalidDate = invalidDate; 11349 proto$1.ordinal = ordinal; 11350 proto$1.preparse = preParsePostFormat; 11351 proto$1.postformat = preParsePostFormat; 11352 proto$1.relativeTime = relativeTime; 11353 proto$1.pastFuture = pastFuture; 11354 proto$1.set = set; 11355 11356 proto$1.months = localeMonths; 11357 proto$1.monthsShort = localeMonthsShort; 11358 proto$1.monthsParse = localeMonthsParse; 11359 proto$1.monthsRegex = monthsRegex; 11360 proto$1.monthsShortRegex = monthsShortRegex; 11361 proto$1.week = localeWeek; 11362 proto$1.firstDayOfYear = localeFirstDayOfYear; 11363 proto$1.firstDayOfWeek = localeFirstDayOfWeek; 11364 11365 proto$1.weekdays = localeWeekdays; 11366 proto$1.weekdaysMin = localeWeekdaysMin; 11367 proto$1.weekdaysShort = localeWeekdaysShort; 11368 proto$1.weekdaysParse = localeWeekdaysParse; 11369 11370 proto$1.weekdaysRegex = weekdaysRegex; 11371 proto$1.weekdaysShortRegex = weekdaysShortRegex; 11372 proto$1.weekdaysMinRegex = weekdaysMinRegex; 11373 11374 proto$1.isPM = localeIsPM; 11375 proto$1.meridiem = localeMeridiem; 11376 11377 function get$1(format, index, field, setter) { 11378 var locale = getLocale(); 11379 var utc = createUTC().set(setter, index); 11380 return locale[field](utc, format); 11381 } 11382 11383 function listMonthsImpl(format, index, field) { 11384 if (isNumber(format)) { 11385 index = format; 11386 format = undefined; 11387 } 11388 11389 format = format || ''; 11390 11391 if (index != null) { 11392 return get$1(format, index, field, 'month'); 11393 } 11394 11395 var i; 11396 var out = []; 11397 for (i = 0; i < 12; i++) { 11398 out[i] = get$1(format, i, field, 'month'); 11399 } 11400 return out; 11401 } 11402 11403 // () 11404 // (5) 11405 // (fmt, 5) 11406 // (fmt) 11407 // (true) 11408 // (true, 5) 11409 // (true, fmt, 5) 11410 // (true, fmt) 11411 function listWeekdaysImpl(localeSorted, format, index, field) { 11412 if (typeof localeSorted === 'boolean') { 11413 if (isNumber(format)) { 11414 index = format; 11415 format = undefined; 11416 } 11417 11418 format = format || ''; 11419 } else { 11420 format = localeSorted; 11421 index = format; 11422 localeSorted = false; 11423 11424 if (isNumber(format)) { 11425 index = format; 11426 format = undefined; 11427 } 11428 11429 format = format || ''; 11430 } 11431 11432 var locale = getLocale(), 11433 shift = localeSorted ? locale._week.dow : 0; 11434 11435 if (index != null) { 11436 return get$1(format, (index + shift) % 7, field, 'day'); 11437 } 11438 11439 var i; 11440 var out = []; 11441 for (i = 0; i < 7; i++) { 11442 out[i] = get$1(format, (i + shift) % 7, field, 'day'); 11443 } 11444 return out; 11445 } 11446 11447 function listMonths(format, index) { 11448 return listMonthsImpl(format, index, 'months'); 11449 } 11450 11451 function listMonthsShort(format, index) { 11452 return listMonthsImpl(format, index, 'monthsShort'); 11453 } 11454 11455 function listWeekdays(localeSorted, format, index) { 11456 return listWeekdaysImpl(localeSorted, format, index, 'weekdays'); 11457 } 11458 11459 function listWeekdaysShort(localeSorted, format, index) { 11460 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort'); 11461 } 11462 11463 function listWeekdaysMin(localeSorted, format, index) { 11464 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin'); 11465 } 11466 11467 getSetGlobalLocale('en', { 11468 dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, 11469 ordinal: function (number) { 11470 var b = number % 10, 11471 output = (toInt(number % 100 / 10) === 1) ? 'th' : 11472 (b === 1) ? 'st' : 11473 (b === 2) ? 'nd' : 11474 (b === 3) ? 'rd' : 'th'; 11475 return number + output; 11476 } 11477 }); 11478 11479 // Side effect imports 11480 11481 hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale); 11482 hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale); 11483 11484 var mathAbs = Math.abs; 11485 11486 function abs() { 11487 var data = this._data; 11488 11489 this._milliseconds = mathAbs(this._milliseconds); 11490 this._days = mathAbs(this._days); 11491 this._months = mathAbs(this._months); 11492 11493 data.milliseconds = mathAbs(data.milliseconds); 11494 data.seconds = mathAbs(data.seconds); 11495 data.minutes = mathAbs(data.minutes); 11496 data.hours = mathAbs(data.hours); 11497 data.months = mathAbs(data.months); 11498 data.years = mathAbs(data.years); 11499 11500 return this; 11501 } 11502 11503 function addSubtract$1(duration, input, value, direction) { 11504 var other = createDuration(input, value); 11505 11506 duration._milliseconds += direction * other._milliseconds; 11507 duration._days += direction * other._days; 11508 duration._months += direction * other._months; 11509 11510 return duration._bubble(); 11511 } 11512 11513 // supports only 2.0-style add(1, 's') or add(duration) 11514 function add$1(input, value) { 11515 return addSubtract$1(this, input, value, 1); 11516 } 11517 11518 // supports only 2.0-style subtract(1, 's') or subtract(duration) 11519 function subtract$1(input, value) { 11520 return addSubtract$1(this, input, value, -1); 11521 } 11522 11523 function absCeil(number) { 11524 if (number < 0) { 11525 return Math.floor(number); 11526 } else { 11527 return Math.ceil(number); 11528 } 11529 } 11530 11531 function bubble() { 11532 var milliseconds = this._milliseconds; 11533 var days = this._days; 11534 var months = this._months; 11535 var data = this._data; 11536 var seconds, minutes, hours, years, monthsFromDays; 11537 11538 // if we have a mix of positive and negative values, bubble down first 11539 // check: https://github.com/moment/moment/issues/2166 11540 if (!((milliseconds >= 0 && days >= 0 && months >= 0) || 11541 (milliseconds <= 0 && days <= 0 && months <= 0))) { 11542 milliseconds += absCeil(monthsToDays(months) + days) * 864e5; 11543 days = 0; 11544 months = 0; 11545 } 11546 11547 // The following code bubbles up values, see the tests for 11548 // examples of what that means. 11549 data.milliseconds = milliseconds % 1000; 11550 11551 seconds = absFloor(milliseconds / 1000); 11552 data.seconds = seconds % 60; 11553 11554 minutes = absFloor(seconds / 60); 11555 data.minutes = minutes % 60; 11556 11557 hours = absFloor(minutes / 60); 11558 data.hours = hours % 24; 11559 11560 days += absFloor(hours / 24); 11561 11562 // convert days to months 11563 monthsFromDays = absFloor(daysToMonths(days)); 11564 months += monthsFromDays; 11565 days -= absCeil(monthsToDays(monthsFromDays)); 11566 11567 // 12 months -> 1 year 11568 years = absFloor(months / 12); 11569 months %= 12; 11570 11571 data.days = days; 11572 data.months = months; 11573 data.years = years; 11574 11575 return this; 11576 } 11577 11578 function daysToMonths(days) { 11579 // 400 years have 146097 days (taking into account leap year rules) 11580 // 400 years have 12 months === 4800 11581 return days * 4800 / 146097; 11582 } 11583 11584 function monthsToDays(months) { 11585 // the reverse of daysToMonths 11586 return months * 146097 / 4800; 11587 } 11588 11589 function as(units) { 11590 if (!this.isValid()) { 11591 return NaN; 11592 } 11593 var days; 11594 var months; 11595 var milliseconds = this._milliseconds; 11596 11597 units = normalizeUnits(units); 11598 11599 if (units === 'month' || units === 'quarter' || units === 'year') { 11600 days = this._days + milliseconds / 864e5; 11601 months = this._months + daysToMonths(days); 11602 switch (units) { 11603 case 'month': return months; 11604 case 'quarter': return months / 3; 11605 case 'year': return months / 12; 11606 } 11607 } else { 11608 // handle milliseconds separately because of floating point math errors (issue #1867) 11609 days = this._days + Math.round(monthsToDays(this._months)); 11610 switch (units) { 11611 case 'week': return days / 7 + milliseconds / 6048e5; 11612 case 'day': return days + milliseconds / 864e5; 11613 case 'hour': return days * 24 + milliseconds / 36e5; 11614 case 'minute': return days * 1440 + milliseconds / 6e4; 11615 case 'second': return days * 86400 + milliseconds / 1000; 11616 // Math.floor prevents floating point math errors here 11617 case 'millisecond': return Math.floor(days * 864e5) + milliseconds; 11618 default: throw new Error('Unknown unit ' + units); 11619 } 11620 } 11621 } 11622 11623 // TODO: Use this.as('ms')? 11624 function valueOf$1() { 11625 if (!this.isValid()) { 11626 return NaN; 11627 } 11628 return ( 11629 this._milliseconds + 11630 this._days * 864e5 + 11631 (this._months % 12) * 2592e6 + 11632 toInt(this._months / 12) * 31536e6 11633 ); 11634 } 11635 11636 function makeAs(alias) { 11637 return function () { 11638 return this.as(alias); 11639 }; 11640 } 11641 11642 var asMilliseconds = makeAs('ms'); 11643 var asSeconds = makeAs('s'); 11644 var asMinutes = makeAs('m'); 11645 var asHours = makeAs('h'); 11646 var asDays = makeAs('d'); 11647 var asWeeks = makeAs('w'); 11648 var asMonths = makeAs('M'); 11649 var asQuarters = makeAs('Q'); 11650 var asYears = makeAs('y'); 11651 11652 function clone$1() { 11653 return createDuration(this); 11654 } 11655 11656 function get$2(units) { 11657 units = normalizeUnits(units); 11658 return this.isValid() ? this[units + 's']() : NaN; 11659 } 11660 11661 function makeGetter(name) { 11662 return function () { 11663 return this.isValid() ? this._data[name] : NaN; 11664 }; 11665 } 11666 11667 var milliseconds = makeGetter('milliseconds'); 11668 var seconds = makeGetter('seconds'); 11669 var minutes = makeGetter('minutes'); 11670 var hours = makeGetter('hours'); 11671 var days = makeGetter('days'); 11672 var months = makeGetter('months'); 11673 var years = makeGetter('years'); 11674 11675 function weeks() { 11676 return absFloor(this.days() / 7); 11677 } 11678 11679 var round = Math.round; 11680 var thresholds = { 11681 ss: 44, // a few seconds to seconds 11682 s: 45, // seconds to minute 11683 m: 45, // minutes to hour 11684 h: 22, // hours to day 11685 d: 26, // days to month 11686 M: 11 // months to year 11687 }; 11688 11689 // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize 11690 function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { 11691 return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); 11692 } 11693 11694 function relativeTime$1(posNegDuration, withoutSuffix, locale) { 11695 var duration = createDuration(posNegDuration).abs(); 11696 var seconds = round(duration.as('s')); 11697 var minutes = round(duration.as('m')); 11698 var hours = round(duration.as('h')); 11699 var days = round(duration.as('d')); 11700 var months = round(duration.as('M')); 11701 var years = round(duration.as('y')); 11702 11703 var a = seconds <= thresholds.ss && ['s', seconds] || 11704 seconds < thresholds.s && ['ss', seconds] || 11705 minutes <= 1 && ['m'] || 11706 minutes < thresholds.m && ['mm', minutes] || 11707 hours <= 1 && ['h'] || 11708 hours < thresholds.h && ['hh', hours] || 11709 days <= 1 && ['d'] || 11710 days < thresholds.d && ['dd', days] || 11711 months <= 1 && ['M'] || 11712 months < thresholds.M && ['MM', months] || 11713 years <= 1 && ['y'] || ['yy', years]; 11714 11715 a[2] = withoutSuffix; 11716 a[3] = +posNegDuration > 0; 11717 a[4] = locale; 11718 return substituteTimeAgo.apply(null, a); 11719 } 11720 11721 // This function allows you to set the rounding function for relative time strings 11722 function getSetRelativeTimeRounding(roundingFunction) { 11723 if (roundingFunction === undefined) { 11724 return round; 11725 } 11726 if (typeof (roundingFunction) === 'function') { 11727 round = roundingFunction; 11728 return true; 11729 } 11730 return false; 11731 } 11732 11733 // This function allows you to set a threshold for relative time strings 11734 function getSetRelativeTimeThreshold(threshold, limit) { 11735 if (thresholds[threshold] === undefined) { 11736 return false; 11737 } 11738 if (limit === undefined) { 11739 return thresholds[threshold]; 11740 } 11741 thresholds[threshold] = limit; 11742 if (threshold === 's') { 11743 thresholds.ss = limit - 1; 11744 } 11745 return true; 11746 } 11747 11748 function humanize(withSuffix) { 11749 if (!this.isValid()) { 11750 return this.localeData().invalidDate(); 11751 } 11752 11753 var locale = this.localeData(); 11754 var output = relativeTime$1(this, !withSuffix, locale); 11755 11756 if (withSuffix) { 11757 output = locale.pastFuture(+this, output); 11758 } 11759 11760 return locale.postformat(output); 11761 } 11762 11763 var abs$1 = Math.abs; 11764 11765 function sign(x) { 11766 return ((x > 0) - (x < 0)) || +x; 11767 } 11768 11769 function toISOString$1() { 11770 // for ISO strings we do not use the normal bubbling rules: 11771 // * milliseconds bubble up until they become hours 11772 // * days do not bubble at all 11773 // * months bubble up until they become years 11774 // This is because there is no context-free conversion between hours and days 11775 // (think of clock changes) 11776 // and also not between days and months (28-31 days per month) 11777 if (!this.isValid()) { 11778 return this.localeData().invalidDate(); 11779 } 11780 11781 var seconds = abs$1(this._milliseconds) / 1000; 11782 var days = abs$1(this._days); 11783 var months = abs$1(this._months); 11784 var minutes, hours, years; 11785 11786 // 3600 seconds -> 60 minutes -> 1 hour 11787 minutes = absFloor(seconds / 60); 11788 hours = absFloor(minutes / 60); 11789 seconds %= 60; 11790 minutes %= 60; 11791 11792 // 12 months -> 1 year 11793 years = absFloor(months / 12); 11794 months %= 12; 11795 11796 11797 // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js 11798 var Y = years; 11799 var M = months; 11800 var D = days; 11801 var h = hours; 11802 var m = minutes; 11803 var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : ''; 11804 var total = this.asSeconds(); 11805 11806 if (!total) { 11807 // this is the same as C#'s (Noda) and python (isodate)... 11808 // but not other JS (goog.date) 11809 return 'P0D'; 11810 } 11811 11812 var totalSign = total < 0 ? '-' : ''; 11813 var ymSign = sign(this._months) !== sign(total) ? '-' : ''; 11814 var daysSign = sign(this._days) !== sign(total) ? '-' : ''; 11815 var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : ''; 11816 11817 return totalSign + 'P' + 11818 (Y ? ymSign + Y + 'Y' : '') + 11819 (M ? ymSign + M + 'M' : '') + 11820 (D ? daysSign + D + 'D' : '') + 11821 ((h || m || s) ? 'T' : '') + 11822 (h ? hmsSign + h + 'H' : '') + 11823 (m ? hmsSign + m + 'M' : '') + 11824 (s ? hmsSign + s + 'S' : ''); 11825 } 11826 11827 var proto$2 = Duration.prototype; 11828 11829 proto$2.isValid = isValid$1; 11830 proto$2.abs = abs; 11831 proto$2.add = add$1; 11832 proto$2.subtract = subtract$1; 11833 proto$2.as = as; 11834 proto$2.asMilliseconds = asMilliseconds; 11835 proto$2.asSeconds = asSeconds; 11836 proto$2.asMinutes = asMinutes; 11837 proto$2.asHours = asHours; 11838 proto$2.asDays = asDays; 11839 proto$2.asWeeks = asWeeks; 11840 proto$2.asMonths = asMonths; 11841 proto$2.asQuarters = asQuarters; 11842 proto$2.asYears = asYears; 11843 proto$2.valueOf = valueOf$1; 11844 proto$2._bubble = bubble; 11845 proto$2.clone = clone$1; 11846 proto$2.get = get$2; 11847 proto$2.milliseconds = milliseconds; 11848 proto$2.seconds = seconds; 11849 proto$2.minutes = minutes; 11850 proto$2.hours = hours; 11851 proto$2.days = days; 11852 proto$2.weeks = weeks; 11853 proto$2.months = months; 11854 proto$2.years = years; 11855 proto$2.humanize = humanize; 11856 proto$2.toISOString = toISOString$1; 11857 proto$2.toString = toISOString$1; 11858 proto$2.toJSON = toISOString$1; 11859 proto$2.locale = locale; 11860 proto$2.localeData = localeData; 11861 11862 proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1); 11863 proto$2.lang = lang; 11864 11865 // Side effect imports 11866 11867 // FORMATTING 11868 11869 addFormatToken('X', 0, 0, 'unix'); 11870 addFormatToken('x', 0, 0, 'valueOf'); 11871 11872 // PARSING 11873 11874 addRegexToken('x', matchSigned);
vendor: 20,694 bytes, lines 11875-12555
11875 addRegexToken('X', matchTimestamp); 11876 addParseToken('X', function (input, array, config) { 11877 config._d = new Date(parseFloat(input, 10) * 1000); 11878 }); 11879 addParseToken('x', function (input, array, config) { 11880 config._d = new Date(toInt(input)); 11881 }); 11882 11883 // Side effect imports 11884 11885 11886 hooks.version = '2.24.0'; 11887 11888 setHookCallback(createLocal); 11889 11890 hooks.fn = proto; 11891 hooks.min = min; 11892 hooks.max = max; 11893 hooks.now = now; 11894 hooks.utc = createUTC; 11895 hooks.unix = createUnix; 11896 hooks.months = listMonths; 11897 hooks.isDate = isDate; 11898 hooks.locale = getSetGlobalLocale; 11899 hooks.invalid = createInvalid; 11900 hooks.duration = createDuration; 11901 hooks.isMoment = isMoment; 11902 hooks.weekdays = listWeekdays; 11903 hooks.parseZone = createInZone; 11904 hooks.localeData = getLocale; 11905 hooks.isDuration = isDuration; 11906 hooks.monthsShort = listMonthsShort; 11907 hooks.weekdaysMin = listWeekdaysMin; 11908 hooks.defineLocale = defineLocale; 11909 hooks.updateLocale = updateLocale; 11910 hooks.locales = listLocales; 11911 hooks.weekdaysShort = listWeekdaysShort; 11912 hooks.normalizeUnits = normalizeUnits; 11913 hooks.relativeTimeRounding = getSetRelativeTimeRounding; 11914 hooks.relativeTimeThreshold = getSetRelativeTimeThreshold; 11915 hooks.calendarFormat = getCalendarFormat; 11916 hooks.prototype = proto; 11917 11918 // currently HTML5 input type only supports 24-hour formats 11919 hooks.HTML5_FMT = { 11920 DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // <input type="datetime-local" /> 11921 DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // <input type="datetime-local" step="1" /> 11922 DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // <input type="datetime-local" step="0.001" /> 11923 DATE: 'YYYY-MM-DD', // <input type="date" /> 11924 TIME: 'HH:mm', // <input type="time" /> 11925 TIME_SECONDS: 'HH:mm:ss', // <input type="time" step="1" /> 11926 TIME_MS: 'HH:mm:ss.SSS', // <input type="time" step="0.001" /> 11927 WEEK: 'GGGG-[W]WW', // <input type="week" /> 11928 MONTH: 'YYYY-MM' // <input type="month" /> 11929 }; 11930 11931 return hooks; 11932 11933}))); 11934 11935 11936//! moment-timezone.js 11937//! version : 0.5.25 11938//! Copyright (c) JS Foundation and other contributors 11939//! license : MIT 11940//! github.com/moment/moment-timezone 11941 11942(function (root, factory) { 11943 "use strict"; 11944 11945 /*global define*/ 11946 if (typeof module === 'object' && module.exports) { 11947 module.exports = factory(require('moment')); // Node 11948 } else if (typeof define === 'function' && define.amd) { 11949 define(['moment'], factory); // AMD 11950 } else { 11951 factory(root.moment); // Browser 11952 } 11953}(this, function (moment) { 11954 "use strict"; 11955 11956 // Do not load moment-timezone a second time. 11957 // if (moment.tz !== undefined) { 11958 // logError('Moment Timezone ' + moment.tz.version + ' was already loaded ' + (moment.tz.dataVersion ? 'with data from ' : 'without any data') + moment.tz.dataVersion); 11959 // return moment; 11960 // } 11961 11962 var VERSION = "0.5.25", 11963 zones = {}, 11964 links = {}, 11965 names = {}, 11966 guesses = {}, 11967 cachedGuess; 11968 11969 if (!moment || typeof moment.version !== 'string') { 11970 logError('Moment Timezone requires Moment.js. See https://momentjs.com/timezone/docs/#/use-it/browser/'); 11971 } 11972 11973 var momentVersion = moment.version.split('.'), 11974 major = +momentVersion[0], 11975 minor = +momentVersion[1]; 11976 11977 // Moment.js version check 11978 if (major < 2 || (major === 2 && minor < 6)) { 11979 logError('Moment Timezone requires Moment.js >= 2.6.0. You are using Moment.js ' + moment.version + '. See momentjs.com'); 11980 } 11981 11982 /************************************ 11983 Unpacking 11984 ************************************/ 11985 11986 function charCodeToInt(charCode) { 11987 if (charCode > 96) { 11988 return charCode - 87; 11989 } else if (charCode > 64) { 11990 return charCode - 29; 11991 } 11992 return charCode - 48; 11993 } 11994 11995 function unpackBase60(string) { 11996 var i = 0, 11997 parts = string.split('.'), 11998 whole = parts[0], 11999 fractional = parts[1] || '', 12000 multiplier = 1, 12001 num, 12002 out = 0, 12003 sign = 1; 12004 12005 // handle negative numbers 12006 if (string.charCodeAt(0) === 45) { 12007 i = 1; 12008 sign = -1; 12009 } 12010 12011 // handle digits before the decimal 12012 for (i; i < whole.length; i++) { 12013 num = charCodeToInt(whole.charCodeAt(i)); 12014 out = 60 * out + num; 12015 } 12016 12017 // handle digits after the decimal 12018 for (i = 0; i < fractional.length; i++) { 12019 multiplier = multiplier / 60; 12020 num = charCodeToInt(fractional.charCodeAt(i)); 12021 out += num * multiplier; 12022 } 12023 12024 return out * sign; 12025 } 12026 12027 function arrayToInt(array) { 12028 for (var i = 0; i < array.length; i++) { 12029 array[i] = unpackBase60(array[i]); 12030 } 12031 } 12032 12033 function intToUntil(array, length) { 12034 for (var i = 0; i < length; i++) { 12035 array[i] = Math.round((array[i - 1] || 0) + (array[i] * 60000)); // minutes to milliseconds 12036 } 12037 12038 array[length - 1] = Infinity; 12039 } 12040 12041 function mapIndices(source, indices) { 12042 var out = [], i; 12043 12044 for (i = 0; i < indices.length; i++) { 12045 out[i] = source[indices[i]]; 12046 } 12047 12048 return out; 12049 } 12050 12051 function unpack(string) { 12052 var data = string.split('|'), 12053 offsets = data[2].split(' '), 12054 indices = data[3].split(''), 12055 untils = data[4].split(' '); 12056 12057 arrayToInt(offsets); 12058 arrayToInt(indices); 12059 arrayToInt(untils); 12060 12061 intToUntil(untils, indices.length); 12062 12063 return { 12064 name: data[0], 12065 abbrs: mapIndices(data[1].split(' '), indices), 12066 offsets: mapIndices(offsets, indices), 12067 untils: untils, 12068 population: data[5] | 0 12069 }; 12070 } 12071 12072 /************************************ 12073 Zone object 12074 ************************************/ 12075 12076 function Zone(packedString) { 12077 if (packedString) { 12078 this._set(unpack(packedString)); 12079 } 12080 } 12081 12082 Zone.prototype = { 12083 _set: function (unpacked) { 12084 this.name = unpacked.name; 12085 this.abbrs = unpacked.abbrs; 12086 this.untils = unpacked.untils; 12087 this.offsets = unpacked.offsets; 12088 this.population = unpacked.population; 12089 }, 12090 12091 _index: function (timestamp) { 12092 var target = +timestamp, 12093 untils = this.untils, 12094 i; 12095 12096 for (i = 0; i < untils.length; i++) { 12097 if (target < untils[i]) { 12098 return i; 12099 } 12100 } 12101 }, 12102 12103 parse: function (timestamp) { 12104 var target = +timestamp, 12105 offsets = this.offsets, 12106 untils = this.untils, 12107 max = untils.length - 1, 12108 offset, offsetNext, offsetPrev, i; 12109 12110 for (i = 0; i < max; i++) { 12111 offset = offsets[i]; 12112 offsetNext = offsets[i + 1]; 12113 offsetPrev = offsets[i ? i - 1 : i]; 12114 12115 if (offset < offsetNext && tz.moveAmbiguousForward) { 12116 offset = offsetNext; 12117 } else if (offset > offsetPrev && tz.moveInvalidForward) { 12118 offset = offsetPrev; 12119 } 12120 12121 if (target < untils[i] - (offset * 60000)) { 12122 return offsets[i]; 12123 } 12124 } 12125 12126 return offsets[max]; 12127 }, 12128 12129 abbr: function (mom) { 12130 return this.abbrs[this._index(mom)]; 12131 }, 12132 12133 offset: function (mom) { 12134 logError("zone.offset has been deprecated in favor of zone.utcOffset"); 12135 return this.offsets[this._index(mom)]; 12136 }, 12137 12138 utcOffset: function (mom) { 12139 return this.offsets[this._index(mom)]; 12140 } 12141 }; 12142 12143 /************************************ 12144 Current Timezone 12145 ************************************/ 12146 12147 function OffsetAt(at) { 12148 var timeString = at.toTimeString(); 12149 var abbr = timeString.match(/\([a-z ]+\)/i); 12150 if (abbr && abbr[0]) { 12151 // 17:56:31 GMT-0600 (CST) 12152 // 17:56:31 GMT-0600 (Central Standard Time) 12153 abbr = abbr[0].match(/[A-Z]/g); 12154 abbr = abbr ? abbr.join('') : undefined; 12155 } else { 12156 // 17:56:31 CST 12157 // 17:56:31 GMT+0800 (å°åæ¨æºæé) 12158 abbr = timeString.match(/[A-Z]{3,5}/g); 12159 abbr = abbr ? abbr[0] : undefined; 12160 } 12161 12162 if (abbr === 'GMT') { 12163 abbr = undefined; 12164 } 12165 12166 this.at = +at; 12167 this.abbr = abbr; 12168 this.offset = at.getTimezoneOffset(); 12169 } 12170 12171 function ZoneScore(zone) { 12172 this.zone = zone; 12173 this.offsetScore = 0; 12174 this.abbrScore = 0; 12175 } 12176 12177 ZoneScore.prototype.scoreOffsetAt = function (offsetAt) { 12178 this.offsetScore += Math.abs(this.zone.utcOffset(offsetAt.at) - offsetAt.offset); 12179 if (this.zone.abbr(offsetAt.at).replace(/[^A-Z]/g, '') !== offsetAt.abbr) { 12180 this.abbrScore++; 12181 } 12182 }; 12183 12184 function findChange(low, high) { 12185 var mid, diff; 12186 12187 while ((diff = ((high.at - low.at) / 12e4 | 0) * 6e4)) { 12188 mid = new OffsetAt(new Date(low.at + diff)); 12189 if (mid.offset === low.offset) { 12190 low = mid; 12191 } else { 12192 high = mid; 12193 } 12194 } 12195 12196 return low; 12197 } 12198 12199 function userOffsets() { 12200 var startYear = new Date().getFullYear() - 2, 12201 last = new OffsetAt(new Date(startYear, 0, 1)), 12202 offsets = [last], 12203 change, next, i; 12204 12205 for (i = 1; i < 48; i++) { 12206 next = new OffsetAt(new Date(startYear, i, 1)); 12207 if (next.offset !== last.offset) { 12208 change = findChange(last, next); 12209 offsets.push(change); 12210 offsets.push(new OffsetAt(new Date(change.at + 6e4))); 12211 } 12212 last = next; 12213 } 12214 12215 for (i = 0; i < 4; i++) { 12216 offsets.push(new OffsetAt(new Date(startYear + i, 0, 1))); 12217 offsets.push(new OffsetAt(new Date(startYear + i, 6, 1))); 12218 } 12219 12220 return offsets; 12221 } 12222 12223 function sortZoneScores(a, b) { 12224 if (a.offsetScore !== b.offsetScore) { 12225 return a.offsetScore - b.offsetScore; 12226 } 12227 if (a.abbrScore !== b.abbrScore) { 12228 return a.abbrScore - b.abbrScore; 12229 } 12230 return b.zone.population - a.zone.population; 12231 } 12232 12233 function addToGuesses(name, offsets) { 12234 var i, offset; 12235 arrayToInt(offsets); 12236 for (i = 0; i < offsets.length; i++) { 12237 offset = offsets[i]; 12238 guesses[offset] = guesses[offset] || {}; 12239 guesses[offset][name] = true; 12240 } 12241 } 12242 12243 function guessesForUserOffsets(offsets) { 12244 var offsetsLength = offsets.length, 12245 filteredGuesses = {}, 12246 out = [], 12247 i, j, guessesOffset; 12248 12249 for (i = 0; i < offsetsLength; i++) { 12250 guessesOffset = guesses[offsets[i].offset] || {}; 12251 for (j in guessesOffset) { 12252 if (guessesOffset.hasOwnProperty(j)) { 12253 filteredGuesses[j] = true; 12254 } 12255 } 12256 } 12257 12258 for (i in filteredGuesses) { 12259 if (filteredGuesses.hasOwnProperty(i)) { 12260 out.push(names[i]); 12261 } 12262 } 12263 12264 return out; 12265 } 12266 12267 function rebuildGuess() { 12268 12269 // use Intl API when available and returning valid time zone 12270 try { 12271 var intlName = Intl.DateTimeFormat().resolvedOptions().timeZone; 12272 if (intlName && intlName.length > 3) { 12273 var name = names[normalizeName(intlName)]; 12274 if (name) { 12275 return name; 12276 } 12277 logError("Moment Timezone found " + intlName + " from the Intl api, but did not have that data loaded."); 12278 } 12279 } catch (e) { 12280 // Intl unavailable, fall back to manual guessing. 12281 } 12282 12283 var offsets = userOffsets(), 12284 offsetsLength = offsets.length, 12285 guesses = guessesForUserOffsets(offsets), 12286 zoneScores = [], 12287 zoneScore, i, j; 12288 12289 for (i = 0; i < guesses.length; i++) { 12290 zoneScore = new ZoneScore(getZone(guesses[i]), offsetsLength); 12291 for (j = 0; j < offsetsLength; j++) { 12292 zoneScore.scoreOffsetAt(offsets[j]); 12293 } 12294 zoneScores.push(zoneScore); 12295 } 12296 12297 zoneScores.sort(sortZoneScores); 12298 12299 return zoneScores.length > 0 ? zoneScores[0].zone.name : undefined; 12300 } 12301 12302 function guess(ignoreCache) { 12303 if (!cachedGuess || ignoreCache) { 12304 cachedGuess = rebuildGuess(); 12305 } 12306 return cachedGuess; 12307 } 12308 12309 /************************************ 12310 Global Methods 12311 ************************************/ 12312 12313 function normalizeName(name) { 12314 return (name || '').toLowerCase().replace(/\//g, '_'); 12315 } 12316 12317 function addZone(packed) { 12318 var i, name, split, normalized; 12319 12320 if (typeof packed === "string") { 12321 packed = [packed]; 12322 } 12323 12324 for (i = 0; i < packed.length; i++) { 12325 split = packed[i].split('|'); 12326 name = split[0]; 12327 normalized = normalizeName(name); 12328 zones[normalized] = packed[i]; 12329 names[normalized] = name; 12330 addToGuesses(normalized, split[2].split(' ')); 12331 } 12332 } 12333 12334 function getZone(name, caller) { 12335 12336 name = normalizeName(name); 12337 12338 var zone = zones[name]; 12339 var link; 12340 12341 if (zone instanceof Zone) { 12342 return zone; 12343 } 12344 12345 if (typeof zone === 'string') { 12346 zone = new Zone(zone); 12347 zones[name] = zone; 12348 return zone; 12349 } 12350 12351 // Pass getZone to prevent recursion more than 1 level deep 12352 if (links[name] && caller !== getZone && (link = getZone(links[name], getZone))) { 12353 zone = zones[name] = new Zone(); 12354 zone._set(link); 12355 zone.name = names[name]; 12356 return zone; 12357 } 12358 12359 return null; 12360 } 12361 12362 function getNames() { 12363 var i, out = []; 12364 12365 for (i in names) { 12366 if (names.hasOwnProperty(i) && (zones[i] || zones[links[i]]) && names[i]) { 12367 out.push(names[i]); 12368 } 12369 } 12370 12371 return out.sort(); 12372 } 12373 12374 function addLink(aliases) { 12375 var i, alias, normal0, normal1; 12376 12377 if (typeof aliases === "string") { 12378 aliases = [aliases]; 12379 } 12380 12381 for (i = 0; i < aliases.length; i++) { 12382 alias = aliases[i].split('|'); 12383 12384 normal0 = normalizeName(alias[0]); 12385 normal1 = normalizeName(alias[1]); 12386 12387 links[normal0] = normal1; 12388 names[normal0] = alias[0]; 12389 12390 links[normal1] = normal0; 12391 names[normal1] = alias[1]; 12392 } 12393 } 12394 12395 function loadData(data) { 12396 addZone(data.zones); 12397 addLink(data.links); 12398 tz.dataVersion = data.version; 12399 } 12400 12401 function zoneExists(name) { 12402 if (!zoneExists.didShowError) { 12403 zoneExists.didShowError = true; 12404 logError("moment.tz.zoneExists('" + name + "') has been deprecated in favor of !moment.tz.zone('" + name + "')"); 12405 } 12406 return !!getZone(name); 12407 } 12408 12409 function needsOffset(m) { 12410 var isUnixTimestamp = (m._f === 'X' || m._f === 'x'); 12411 return !!(m._a && (m._tzm === undefined) && !isUnixTimestamp); 12412 } 12413 12414 function logError(message) { 12415 if (typeof console !== 'undefined' && typeof console.error === 'function') { 12416 console.error(message); 12417 } 12418 } 12419 12420 /************************************ 12421 moment.tz namespace 12422 ************************************/ 12423 12424 function tz(input) { 12425 var args = Array.prototype.slice.call(arguments, 0, -1), 12426 name = arguments[arguments.length - 1], 12427 zone = getZone(name), 12428 out = moment.utc.apply(null, args); 12429 12430 if (zone && !moment.isMoment(input) && needsOffset(out)) { 12431 out.add(zone.parse(out), 'minutes'); 12432 } 12433 12434 out.tz(name); 12435 12436 return out; 12437 } 12438 12439 tz.version = VERSION; 12440 tz.dataVersion = ''; 12441 tz._zones = zones; 12442 tz._links = links; 12443 tz._names = names; 12444 tz.add = addZone; 12445 tz.link = addLink; 12446 tz.load = loadData; 12447 tz.zone = getZone; 12448 tz.zoneExists = zoneExists; // deprecated in 0.1.0 12449 tz.guess = guess; 12450 tz.names = getNames; 12451 tz.Zone = Zone; 12452 tz.unpack = unpack; 12453 tz.unpackBase60 = unpackBase60; 12454 tz.needsOffset = needsOffset; 12455 tz.moveInvalidForward = true; 12456 tz.moveAmbiguousForward = false; 12457 12458 /************************************ 12459 Interface with Moment.js 12460 ************************************/ 12461 12462 var fn = moment.fn; 12463 12464 moment.tz = tz; 12465 12466 moment.defaultZone = null; 12467 12468 moment.updateOffset = function (mom, keepTime) { 12469 var zone = moment.defaultZone, 12470 offset; 12471 12472 if (mom._z === undefined) { 12473 if (zone && needsOffset(mom) && !mom._isUTC) { 12474 mom._d = moment.utc(mom._a)._d; 12475 mom.utc().add(zone.parse(mom), 'minutes'); 12476 } 12477 mom._z = zone; 12478 } 12479 if (mom._z) { 12480 offset = mom._z.utcOffset(mom); 12481 if (Math.abs(offset) < 16) { 12482 offset = offset / 60; 12483 } 12484 if (mom.utcOffset !== undefined) { 12485 var z = mom._z; 12486 mom.utcOffset(-offset, keepTime); 12487 mom._z = z; 12488 } else { 12489 mom.zone(offset, keepTime); 12490 } 12491 } 12492 }; 12493 12494 fn.tz = function (name, keepTime) { 12495 if (name) { 12496 if (typeof name !== 'string') { 12497 throw new Error('Time zone name must be a string, got ' + name + ' [' + typeof name + ']'); 12498 } 12499 this._z = getZone(name); 12500 if (this._z) { 12501 moment.updateOffset(this, keepTime); 12502 } else { 12503 logError("Moment Timezone has no data for " + name + ". See http://momentjs.com/timezone/docs/#/data-loading/."); 12504 } 12505 return this; 12506 } 12507 if (this._z) { return this._z.name; } 12508 }; 12509 12510 function abbrWrap(old) { 12511 return function () { 12512 if (this._z) { return this._z.abbr(this); } 12513 return old.call(this); 12514 }; 12515 } 12516 12517 function resetZoneWrap(old) { 12518 return function () { 12519 this._z = null; 12520 return old.apply(this, arguments); 12521 }; 12522 } 12523 12524 function resetZoneWrap2(old) { 12525 return function () { 12526 if (arguments.length > 0) this._z = null; 12527 return old.apply(this, arguments); 12528 }; 12529 } 12530 12531 fn.zoneName = abbrWrap(fn.zoneName); 12532 fn.zoneAbbr = abbrWrap(fn.zoneAbbr); 12533 fn.utc = resetZoneWrap(fn.utc); 12534 fn.local = resetZoneWrap(fn.local); 12535 fn.utcOffset = resetZoneWrap2(fn.utcOffset); 12536 12537 moment.tz.setDefault = function (name) { 12538 if (major < 2 || (major === 2 && minor < 9)) { 12539 logError('Moment Timezone setDefault() requires Moment.js >= 2.9.0. You are using Moment.js ' + moment.version + '.'); 12540 } 12541 moment.defaultZone = name ? getZone(name) : null; 12542 return moment; 12543 }; 12544 12545 // Cloning a moment should include the _z property. 12546 var momentProperties = moment.momentProperties; 12547 if (Object.prototype.toString.call(momentProperties) === '[object Array]') { 12548 // moment 2.8.1+ 12549 momentProperties.push('_z'); 12550 momentProperties.push('_a'); 12551 } else if (momentProperties) { 12552 // moment 2.7.0 12553 momentProperties._z = null; 12554 } 12555
12556 loadData({ 12557 "version": "2019a", 12558 "zones": [ 12559 "Africa/Abidjan|GMT|0|0||48e5", 12560 "Africa/Nairobi|EAT|-30|0||47e5", 12561 "Africa/Algiers|WET WEST CET CEST|0 -10 -10 -20|01012320102|3bX0 11A0 dDd0 17b0 11B0 1cN0 2Dy0 1cN0 1fB0 1cL0|26e5", 12562 "Africa/Lagos|WAT|-10|0||17e6", 12563 "Africa/Bissau|-01 GMT|10 0|01|cap0|39e4", 12564 "Africa/Maputo|CAT|-20|0||26e5", 12565 "Africa/Cairo|EET EEST|-20 -30|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|LX0 11d0 1oL0 11d0 1pb0 11d0 1oL0 11d0 1oL0 11d0 1oL0 11d0 1pb0 11d0 1oL0 11d0 1oL0 11d0 1oL0 11d0 1pb0 11d0 1oL0 11d0 1WL0 rd0 1Rz0 wp0 1pb0 11d0 1oL0 11d0 1oL0 11d0 1oL0 11d0 1pb0 11d0 1qL0 Xd0 1oL0 11d0 1oL0 11d0 1pb0 11d0 1oL0 11d0 1oL0 11d0 1ny0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 WL0 1qN0 Rb0 1wp0 On0 1zd0 Lz0 1EN0 Fb0 c10 8n0 8Nd0 gL0 e10 mn0|15e6", 12566 "Africa/Casablanca|+00 +01|0 -10|01010101010101010101010101010101010101010101010101010101010101010101010|aS00 rz0 43d0 AL0 1Nd0 XX0 1Cp0 pz0 dEp0 4mn0 SyN0 AL0 1Nd0 wn0 1FB0 Db0 1zd0 Lz0 1Nf0 wM0 co0 go0 1o00 s00 dA0 vc0 11A0 A00 e00 y00 11A0 uM0 e00 Dc0 11A0 s00 e00 IM0 WM0 mo0 gM0 LA0 WM0 jA0 e
1256600 28M0 e00 2600 e00 28M0 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 28M0 e00 2600 e00 28M0 e00 2600 gM0 2600|32e5", 12567 "Africa/Ceuta|WET WEST CET CEST|0 -10 -10 -20|0101010102323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|aS00 rz0 43d0 AL0 1Nd0 XX0 1Cp0 pz0 dEp0 4VB0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|85e3", 12568 "Africa/El_Aaiun|-01 +00 +01|10 0 -10|01212121212121212121212121212121212121212121212121212121212121212121|fi10 6L0 AL0 1Nd0 XX0 1Cp0 pz0 1cBB0 AL0 1Nd0 wn0 1FB0 Db0 1zd0 Lz0 1Nf0 wM0 co0 go0 1o00 s00 dA0 vc0 11A0 A00 e00 y00 11A0 uM0 e00 Dc0 11A0 s00 e00 IM0 WM0 mo0 gM0 LA0 WM0 jA0 e
1256800 28M0 e00 2600 e00 28M0 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 28M0 e00 2600 e00 28M0 e00 2600 gM0 2600|20e4", 12569 "Africa/Johannesburg|SAST|-20|0||84e5", 12570 "Africa/Juba|CAT CAST EAT|-20 -30 -30|0101010101010101010101010101010102|LW0 16L0 1iN0 17b0 1jd0 17b0 1ip0 17z0 1i10 17X0 1hB0 18n0 1hd0 19b0 1gp0 19z0 1iN0 17b0 1ip0 17z0 1i10 18n0 1hd0 18L0 1gN0 19b0 1gp0 19z0 1iN0 17z0 1i10 17X0 yGd0", 12571 "Africa/Khartoum|CAT CAST EAT|-20 -30 -30|01010101010101010101010101010101020|LW0 16L0 1iN0 17b0 1jd0 17b0 1ip0 17z0 1i10 17X0 1hB0 18n0 1hd0 19b0 1gp0 19z0 1iN0 17b0 1ip0 17z0 1i10 18n0 1hd0 18L0 1gN0 19b0 1gp0 19z0 1iN0 17z0 1i10 17X0 yGd0 HjL0|51e5", 12572 "Africa/Monrovia|MMT GMT|I.u 0|01|4SoI.u|11e5", 12573 "Africa/Ndjamena|WAT WAST|-10 -20|010|nNb0 Wn0|13e5", 12574 "Africa/Sao_Tome|GMT WAT|0 -10|010|1UQN0 2q00", 12575 "Africa/Tripoli|EET CET CEST|-20 -10 -20|0121212121212121210120120|tda0 A10 1db0 1cN0 1db0 1dd0 1db0 1eN0 1bb0 1e10 1cL0 1c10 1db0 1dd0 1db0 1cN0 1db0 1q10 fAn0 1ep0 1db0 AKq0 TA0 1o00|11e5", 12576 "Africa/Tunis|CET CEST|-10 -20|0101010101010101010|hOn0 WM0 1rA0 11c0 nwo0 Ko0 1cM0 1cM0 1rA0 10M0 zuM0 10N0 1aN0 1qM0 WM0 1qM0 11A0 1o00|20e5", 12577 "Africa/Windhoek|SAST CAT WAT|-20 -20 -10|01212121212121212121212121212121212121212121212121|Ndy0 9Io0 16P0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0|32e4", 12578 "America/Adak|BST BDT AHST HST HDT|b0 a0 a0 a0 90|0101010101010101010101010101234343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343|Kd0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 cm0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|326", 12579 "America/Anchorage|AHST AHDT YST AKST AKDT|a0 90 90 90 80|0101010101010101010101010101234343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343|Kc0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 cm0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|30e4", 12580 "America/Puerto_Rico|AST|40|0||24e5", 12581 "America/Araguaina|-03 -02|30 20|01010101010101010101010101010|CxD0 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 dMN0 Lz0 1zd0 Rb0 1wN0 Wn0 1tB0 Rb0 1tB0 WL0 1tB0 Rb0 1zd0 On0 1HB0 FX0 ny10 Lz0|14e4", 12582 "America/Argentina/Buenos_Aires|-03 -02|30 20|01010101010101010|9Rf0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wp0 Rb0 1wp0 TX0 A4p0 uL0 1qN0 WL0", 12583 "America/Argentina/Catamarca|-03 -02 -04|30 20 40|01010101210102010|9Rf0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wq0 Ra0 1wp0 TX0 rlB0 7B0 8zb0 uL0", 12584 "America/Argentina/Cordoba|-03 -02 -04|30 20 40|01010101210101010|9Rf0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wq0 Ra0 1wp0 TX0 A4p0 uL0 1qN0 WL0", 12585 "America/Argentina/Jujuy|-03 -02 -04|30 20 40|010101202101010|9Rf0 Db0 zvd0 Bz0 1tB0 TX0 1ze0 TX0 1ld0 WK0 1wp0 TX0 A4p0 uL0", 12586 "America/Argentina/La_Rioja|-03 -02 -04|30 20 40|010101012010102010|9Rf0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Qn0 qO0 16n0 Rb0 1wp0 TX0 rlB0 7B0 8zb0 uL0", 12587 "America/Argentina/Mendoza|-03 -02 -04|30 20 40|01010120202102010|9Rf0 Db0 zvd0 Bz0 1tB0 TX0 1u20 SL0 1vd0 Tb0 1wp0 TW0 ri10 Op0 7TX0 uL0", 12588 "America/Argentina/Rio_Gallegos|-03 -02 -04|30 20 40|01010101010102010|9Rf0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wp0 Rb0 1wp0 TX0 rlB0 7B0 8zb0 uL0", 12589 "America/Argentina/Salta|-03 -02 -04|30 20 40|010101012101010|9Rf0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wq0 Ra0 1wp0 TX0 A4p0 uL0", 12590 "America/Argentina/San_Juan|-03 -02 -04|30 20 40|010101012010102010|9Rf0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Qn0 qO0 16n0 Rb0 1wp0 TX0 rld0 m10 8lb0 uL0", 12591 "America/Argentina/San_Luis|-03 -02 -04|30 20 40|010101202020102020|9Rf0 Db0 zvd0 Bz0 1tB0 XX0 1q20 SL0 AN0 vDb0 m10 8lb0 8L0 jd0 1qN0 WL0 1qN0", 12592 "America/Argentina/Tucuman|-03 -02 -04|30 20 40|0101010121010201010|9Rf0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wq0 Ra0 1wp0 TX0 rlB0 4N0 8BX0 uL0 1qN0 WL0", 12593 "America/Argentina/Ushuaia|-03 -02 -04|30 20 40|01010101010102010|9Rf0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wp0 Rb0 1wp0 TX0 rkN0 8p0 8zb0 uL0", 12594 "America/Asuncion|-04 -03|40 30|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|6FE0 3CL0 3Dd0 10L0 1pB0 10n0 1pB0 10n0 1pB0 1cL0 1dd0 1db0 1dd0 1cL0 1dd0 1cL0 1dd0 1cL0 1dd0 1db0 1dd0 1cL0 1dd0 1cL0 1dd0 1cL0 1dd0 1db0 1dd0 1cL0 1lB0 14n0 1dd0 1cL0 1fd0 WL0 1rd0 1aL0 1dB0 Xz0 1qp0 Xb0 1qN0 10L0 1rB0 TX0 1tB0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 1cL0 WN0 1qL0 11B0 1nX0 1ip0 WL0 1qN0 WL0 1qN0 WL0 1tB0 TX0 1tB0 TX0 1tB0 19X0 1a10 1fz0 1a10 1fz0 1cN0 17b0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1fB0 19X0 1fB0 19X0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1fB0 19X0 1fB0 19X0 1fB0 19X0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1fB0 19X0 1fB0 19X0 1ip0 17b0 1ip0|28e5", 12595 "America/Panama|EST|50|0||15e5", 12596 "America/Bahia_Banderas|PST MST MDT CDT CST|80 70 60 50 60|012121212121212121212121212121343434343434343434343434343434343434343434|80 13Vd0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nW0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0|84e3",
12597 "America/Bahia|-03 -02|30 20|010101010101010101010101010101010101010|CxD0 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 1EN0 Lz0 1C10 IL0 1HB0 Db0 1HB0 On0 1zd0 On0 1zd0 Lz0 1zd0 Rb0 1wN0 Wn0 1tB0 Rb0 1tB0 WL0 1tB0 Rb0 1zd0 On0 1HB0 FX0 l5B0 Rb0|27e5", 12598 "America/Barbados|AST ADT|40 30|010101010|i7G0 IL0 1ip0 17b0 1ip0 17b0 1ld0 13b0|28e4", 12599 "America/Belem|-03 -02|30 20|0101010|CxD0 Rb0 1tB0 IL0 1Fd0 FX0|20e5", 12600 "America/Belize|CST CDT|60 50|01010|9xG0 qn0 lxB0 mn0|57e3", 12601 "America/Boa_Vista|-04 -03|40 30|01010101010|CxE0 Rb0 1tB0 IL0 1Fd0 FX0 smp0 WL0 1tB0 2L0|62e2", 12602 "America/Bogota|-05 -04|50 40|010|Snh0 2en0|90e5", 12603 "America/Boise|MST MDT|70 60|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K90 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 Dd0 1Kn0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|21e4", 12604 "America/Cambridge_Bay|MST MDT CST CDT EST|70 60 60 50 50|01010101010101010101010101010101010101012342101010101010101010101010101010101010101010101010101010101010|p7J0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11A0 1nX0 2K0 WQ0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|15e2", 12605 "America/Campo_Grande|-04 -03|40 30|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|CxE0 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 1EN0 Lz0 1C10 IL0 1HB0 Db0 1HB0 On0 1zd0 On0 1zd0 Lz0 1zd0 Rb0 1wN0 Wn0 1tB0 Rb0 1tB0 WL0 1tB0 Rb0 1zd0 On0 1HB0 FX0 1C10 Lz0 1Ip0 HX0 1zd0 On0 1HB0 IL0 1wp0 On0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 Rb0 1zd0 Lz0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 On0 1zd0 On0 1HB0 FX0 1HB0 FX0 1HB0 IL0 1HB0 FX0 1HB0 IL0 1EN0 FX0 1HB0 FX0 1HB0 IL0 1EN0 IL0 1HB0 FX0 1HB0 FX0 1HB0 FX0 1HB0|77e4", 12606 "America/Cancun|CST EST EDT CDT|60 50 40 50|012121230303030303030303030303030303030301|t9G0 yLB0 1lb0 14p0 1lb0 14p0 Lz0 xB0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 Dd0|63e4", 12607 "America/Caracas|-04 -0430|40 4u|010|1wmv0 kqo0|29e5", 12608 "America/Cayenne|-03|30|0||58e3", 12609 "America/Chicago|CST CDT|60 50|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K80 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|92e5", 12610 "America/Chihuahua|CST CDT MDT MST|60 50 60 70|01010232323232323232323232323232323232323232323232323232323232323232323|13Vk0 1lb0 14p0 1lb0 14q0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0|81e4", 12611 "America/Costa_Rica|CST CDT|60 50|010101010|mgS0 Db0 1Kp0 Db0 pRB0 15b0 1kp0 mL0|12e5", 12612 "America/Phoenix|MST|70|0||42e5", 12613 "America/Cuiaba|-04 -03|40 30|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|CxE0 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 1EN0 Lz0 1C10 IL0 1HB0 Db0 1HB0 On0 1zd0 On0 1zd0 Lz0 1zd0 Rb0 1wN0 Wn0 1tB0 Rb0 1tB0 WL0 1tB0 Rb0 1zd0 On0 1HB0 FX0 4a10 HX0 1zd0 On0 1HB0 IL0 1wp0 On0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 Rb0 1zd0 Lz0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 On0 1zd0 On0 1HB0 FX0 1HB0 FX0 1HB0 IL0 1HB0 FX0 1HB0 IL0 1EN0 FX0 1HB0 FX0 1HB0 IL0 1EN0 IL0 1HB0 FX0 1HB0 FX0 1HB0 FX0 1HB0|54e4", 12614 "America/Danmarkshavn|-03 -02 GMT|30 20 0|0101010101010101010101010101010102|oXh0 19U0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 DC0|8",
12615 "America/Dawson_Creek|PST PDT MST|80 70 70|0101012|Ka0 1cL0 1cN0 1fz0 1cN0 ML0|12e3", 12616 "America/Dawson|YST PST PDT|90 80 70|01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|9ix0 fNd0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|13e2", 12617 "America/Denver|MST MDT|70 60|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K90 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|26e5", 12618 "America/Detroit|EST EDT|50 40|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|85H0 1cL0 s10 1Vz0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|37e5", 12619 "America/Edmonton|MST MDT|70 60|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|5E90 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|10e5", 12620 "America/Eirunepe|-05 -04|50 40|01010101010|CxF0 Rb0 1tB0 IL0 1Fd0 FX0 dPB0 On0 yTd0 d5X0|31e3", 12621 "America/El_Salvador|CST CDT|60 50|01010|Gcu0 WL0 1qN0 WL0|11e5", 12622 "America/Tijuana|PST PDT|80 70|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|fmy0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 U10 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|20e5", 12623 "America/Fort_Nelson|PST PDT MST|80 70 70|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010102|Ka0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0|39e2", 12624 "America/Fort_Wayne|EST EDT|50 40|01010101010101010101010101010101010101010101010101010|K70 1cL0 1qhd0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0", 12625 "America/Fortaleza|-03 -02|30 20|01010101010101010|CxD0 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 nsp0 WL0 1tB0 5z0 2mN0 On0|34e5", 12626 "America/Glace_Bay|AST ADT|40 30|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|5E60 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|19e3", 12627 "America/Godthab|-03 -02|30 20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|oXh0 19U0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|17e3", 12628 "America/Goose_Bay|AST ADT ADDT|40 30 20|010101010101010101010101010101010101020101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K60 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14n1 1lb0 14p0 1nW0 11C0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zcX Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|76e2", 12629 "America/Grand_Turk|EST EDT AST|50 40 40|01010101010101010101010101010101010101010101010101010101010101010101010101210101010101010101010101010|mG70 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 5Ip0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|37e2", 12630 "America/Guatemala|CST CDT|60 50|010101010|9tG0 An0 mtd0 Nz0 ifB0 17b0 zDB0 11z0|13e5", 12631 "America/Guayaquil|-05 -04|50 40|010|TKR0 rz0|27e5", 12632 "America/Guyana|-0345 -03 -04|3J 30 40|012|dyPJ Bxbf|80e4", 12633 "America/Halifax|AST ADT|40 30|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K60 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|39e4", 12634 "America/Havana|CST CDT|50 40|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K50 1cL0 1cN0 1fz0 1cN0 14n0 1ld0 14L0 1kN0 15b0 1kp0 1cL0 1cN0 1fz0 1a10 1fz0 1fB0 11z0 14p0 1nX0 11B0 1nX0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 14n0 1ld0 14n0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 1a10 1in0 1a10 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 17c0 1o00 11A0 1qM0 11A0 1o00 11A0 1o00 14o0 1lc0 14o0 1lc0 11A0 6i00 Rc0 1wo0 U00 1tA0 Rc0 1wo0 U00 1wo0 U00 1zc0 U00 1qM0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0|21e5", 12635 "America/Hermosillo|PST MST MDT|80 70 60|01212121|80 13Vd0 1lb0 14p0 1lb0 14p0 1lb0|64e4", 12636 "America/Indiana/Knox|CST CDT EST|60 50 50|01010101010101010101010101010101010101010101210101010101010101010101010101010101010101010101010|K80 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 z8o0 1o00 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0", 12637 "America/Indiana/Marengo|EST EDT CDT|50 40 50|010101010201010101010101010101010101010101010101010101010101010|K70 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1VA0 LA0 1BX0 1e6p0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0", 12638 "America/Indiana/Petersburg|CST CDT EST EDT|60 50 50 40|0101010101010101210123232323232323232323232323232323232323232323232|K80 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 19co0 1o00 Rd0 1zb0 Oo0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0", 12639 "America/Indiana/Tell_City|EST EDT CDT CST|50 40 50 60|01023232323232323232323232323232323232323232323232323|K70 1cL0 1qhd0 1o00 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0", 12640 "America/Indiana/Vevay|EST EDT|50 40|010101010101010101010101010101010101010101010101010101010|K70 1cL0 1cN0 1fz0 1cN0 1cL0 1lnd0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0", 12641 "America/Indiana/Vincennes|EST EDT CDT CST|50 40 50 60|01023201010101010101010101010101010101010101010101010|K70 1cL0 1qhd0 1o00 Rd0 1zb0 Oo0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0", 12642 "America/Indiana/Winamac|EST EDT CDT CST|50 40 50 60|01023101010101010101010101010101010101010101010101010|K70 1cL0 1qhd0 1o00 Rd0 1za0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0", 12643 "America/Inuvik|PST MST MDT|80 70 60|01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|mGa0 2pz0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|35e2", 12644 "America/Iqaluit|EST EDT CST CDT|50 40 60 50|0101010101010101010101010101010101010101230101010101010101010101010101010101010101010101010101010101010|p7H0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11C0 1nX0 11A0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|67e2", 12645 "America/Jamaica|EST EDT|50 40|010101010101010101010|9Kv0 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0|94e4", 12646 "America/Juneau|PST PDT YDT YST AKST AKDT|80 70 80 90 90 80|0101010101010101010102010101345454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454|Ka0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cM0 1cM0 1cL0 1cN0 1fz0 1a10 1fz0 co0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|33e3", 12647 "America/Kentucky/Louisville|EST EDT CDT|50 40 50|010101010201010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K70 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1VA0 LA0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0", 12648 "America/Kentucky/Monticello|CST CDT EST EDT|60 50 50 40|010101010101010101010101010101010101010101010101010101010101012323232323232323232323232323232323232323232323232323232323232|K80 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11A0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0", 12649 "America/La_Paz|-04|40|0||19e5", 12650 "America/Lima|-05 -04|50 40|010101
12650010|CVF0 zX0 1O10 zX0 6Gp0 zX0 98p0 zX0|11e6", 12651 "America/Los_Angeles|PST PDT|80 70|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|Ka0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|15e6", 12652 "America/Maceio|-03 -02|30 20|0101010101010101010|CxD0 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 dMN0 Lz0 8Q10 WL0 1tB0 5z0 2mN0 On0|93e4", 12653 "America/Managua|CST EST CDT|60 50 50|010202010102020|86u0 4mn0 9Up0 Dz0 1K10 Dz0 s3F0 1KH0 DB0 9In0 k8p0 19X0 1o30 11y0|22e5", 12654 "America/Manaus|-04 -03|40 30|010101010|CxE0 Rb0 1tB0 IL0 1Fd0 FX0 dPB0 On0|19e5", 12655 "America/Martinique|AST ADT|40 30|010|oXg0 19X0|39e4", 12656 "America/Matamoros|CST CDT|60 50|0101010101010101010101010101010101010101010101010101010101010101010101010|IqU0 1nX0 i6p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 U10 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|45e4", 12657 "America/Mazatlan|PST MST MDT|80 70 60|012121212121212121212121212121212121212121212121212121212121212121212121|80 13Vd0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0|44e4", 12658 "America/Menominee|EST CDT CST|50 50 60|012121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212|85H0 1cM0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|85e2",
12659 "America/Merida|CST EST CDT|60 50 50|0102020202020202020202020202020202020202020202020202020202020202020202020|t9G0 2hz0 wu30 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0|11e5", 12660 "America/Metlakatla|PST PDT AKST AKDT|80 70 90 80|0101010101010101010101010101023232302323232323232323232323232|Ka0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1hU10 Rd0 1zb0 Op0 1zb0 Op0 1zb0 uM0 jB0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|14e2", 12661 "America/Mexico_City|CST CDT|60 50|01010101010101010101010101010101010101010101010101010101010101010101010|13Vk0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0|20e6", 12662 "America/Miquelon|AST -03 -02|40 30 20|012121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|p9g0 gQ10 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|61e2", 12663 "America/Moncton|AST ADT|40 30|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K60 1cL0 1cN0 1fz0 1cN0 1cL0 3Cp0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14n1 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 ReX 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|64e3", 12664 "America/Monterrey|CST CDT|60 50|0101010101010101010101010101010101010101010101010101010101010101010101010|IqU0 1nX0 i6p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0|41e5", 12665 "America/Montevideo|-03 -02 -0130 -0230|30 20 1u 2u|0101023010101010101010101010101010101010101010101010|JD0 jX0 4vB0 xz0 3Cp0 mmu 1a10 IMu Db0 4c10 uL0 1Nd0 An0 1SN0 uL0 mp0 28L0 iPB0 un0 1SN0 xz0 1zd0 Lz0 1zd0 Rb0 1zd0 On0 1wp0 Rb0 s8p0 1fB0 1ip0 11z0 1ld0 14n0 1o10 11z0 1o10 11z0 1o10 14n0 1ld0 14n0 1ld0 14n0 1o10 11z0 1o10 11z0 1o10 11z0|17e5", 12666 "America/Toronto|EST EDT|50 40|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K70 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|65e5",
12667 "America/New_York|EST EDT|50 40|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K70 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|21e6", 12668 "America/Nipigon|EST EDT|50 40|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|avj0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|16e2", 12669 "America/Nome|BST BDT YST AKST AKDT|b0 a0 90 90 80|0101010101010101010101010101234343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343|Kd0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 cl0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|38e2", 12670 "America/Noronha|-02 -01|20 10|01010101010101010|CxC0 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 nsp0 WL0 1tB0 2L0 2pB0 On0|30e2", 12671 "America/North_Dakota/Beulah|MST MDT CST CDT|70 60 60 50|010101010101010101010101010101010101010101010101010101010101010101010101010101010123232323232323232323232323232323232323232|K90 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Oo0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0", 12672 "America/North_Dakota/Center|MST MDT CST CDT|70 60 60 50|010101010101010101010101010101010101010101010123232323232323232323232323232323232323232323232323232323232323232323232323232|K90 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14o0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0", 12673 "America/North_Dakota/New_Salem|MST MDT CST CDT|70 60 60 50|010101010101010101010101010101010101010101010101010101010101010101012323232323232323232323232323232323232323232323232323232|K90 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14o0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0", 12674 "America/Ojinaga|CST CDT MDT MST|60 50 60 70|01010232323232323232323232323232323232323232323232323232323232323232323|13Vk0 1lb0 14p0 1lb0 14q0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 U10 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|23e3", 12675 "America/Pangnirtung|AST ADT EDT EST CST CDT|40 30 40 50 60 50|0101010101010101010101010101010232323232453232323232323232323232323232323232323232323232323232323232323|p7G0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1o00 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11C0 1nX0 11A0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|14e2", 12676 "America/Paramaribo|-0330 -03|3u 30|01|zSPu|24e4", 12677 "America/Port-au-Prince|EST EDT|50 40|01010101010101010101010101010101010101010101010101010101010101010101010|wu50 19X0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14q0 1o00 11A0 1o00 11A0 1o00 14o0 1lc0 14o0 1lc0 14o0 1o00 11A0 1o00 11A0 1o00 14o0 1lc0 14o0 1lc0 i6n0 1nX0 11B0 1nX0 d430 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 3iN0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|23e5", 12678 "America/Rio_Branco|-05 -04|50 40|010101010|CxF0 Rb0 1tB0 IL0 1Fd0 FX0 NBd0 d5X0|31e4", 12679 "America/Porto_Velho|-04 -03|40 30|0101010|CxE0 Rb0 1tB0 IL0 1Fd0 FX0|37e4", 12680 "America/Punta_Arenas|-03 -04|30 40|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|yP0 1ip0 11z0 1o10 11z0 1qN0 WL0 1ld0 14n0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 1cL0 1cN0 11z0 1o10 11z0 1qN0 WL0 1fB0 19X0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1ip0 1fz0 1fB0 11z0 1qN0 WL0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1o10 19X0 1fB0 1nX0 G10 1EL0 Op0 1zb0 Rd0 1wn0 Rd0 46n0 Ap0", 12681 "America/Rainy_River|CST CDT|60 50|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|avk0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|842", 12682 "America/Rankin_Inlet|CST CDT EST|60 50 50|0101010101010101010101010101010101010101012101010101010101010101010101010101010101010101010101010101010|p7I0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|26e2", 12683 "America/Recife|-03 -02|30 20|01010101010101010|CxD0 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 nsp0 WL0 1tB0 2L0 2pB0 On0|33e5", 12684 "America/Regina|CST|60|0||19e4", 12685 "America/Resolute|CST CDT EST|60 50 50|0101010101010101010101010101010101010101012101010101012101010101010101010101010101010101010101010101010|p7I0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|229", 12686 "America/Santarem|-04 -03|40 30|01010101|CxE0 Rb0 1tB0 IL0 1Fd0 FX0 NBd0|21e4", 12687 "America/Santiago|-03 -04|30 40|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|yP0 1ip0 11z0 1o10 11z0 1qN0 WL0 1ld0 14n0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 1cL0 1cN0 11z0 1o10 11z0 1qN0 WL0 1fB0 19X0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1ip0 1fz0 1fB0 11z0 1qN0 WL0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1o10 19X0 1fB0 1nX0 G10 1EL0 Op0 1zb0 Rd0 1wn0 Rd0 46n0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1zb0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0|62e5", 12688 "America/Santo_Domingo|-0430 EST AST|4u 50 40|0101010101212|ksu 1Cou yLu 1RAu wLu 1QMu xzu 1Q0u xXu 1PAu 13jB0 e00|29e5", 12689 "America/Sao_Paulo|-03 -02|30 20|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|CxD0 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 1EN0 Lz0 1C10 IL0 1HB0 Db0 1HB0 On0 1zd0 On0 1zd0 Lz0 1zd0 Rb0 1wN0 Wn0 1tB0 Rb0 1tB0 WL0 1tB0 Rb0 1zd0 On0 1HB0 FX0 1C10 Lz0 1Ip0 HX0 1zd0 On0 1HB0 IL0 1wp0 On0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 Rb0 1zd0 Lz0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 On0 1zd0 On0 1HB0 FX0 1HB0 FX0 1HB0 IL0 1HB0 FX0 1HB0 IL0 1EN0 FX0 1HB0 FX0 1HB0 IL0 1EN0 IL0 1HB0 FX0 1HB0 FX0 1HB0 FX0 1HB0|20e6", 12690 "America/Scoresbysund|-02 -01 +00|20 10 0|0102121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|oXg0 1a00 1cK0 1cL0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|452", 12691 "America/Sitka|PST PDT YST AKST AKDT|80 70 90 90 80|0101010101010101010101010101234343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343|Ka0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 co0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|90e2", 12692 "America/St_Johns|NST NDT NDDT|3u 2u 1u|010101010101010101010101010101010101020101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K5u 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14n1 1lb0 14p0 1nW0 11C0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zcX Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|11e4", 12693 "America/Swift_Current|MST CST|70 60|01|5E90|16e3", 12694 "America/Tegucigalpa|CST CDT|60 50|0101010|Gcu0 WL0 1qN0 WL0 GRd0 AL0|11e5", 12695 "America/Thule|AST ADT|40 30|010101010101010101010101010101010101010101010101010101010101010101010101010101010|PHG0 1cL0 1cN0 1cL0 1fB0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|656", 12696 "America/Thunder_Bay|EST EDT|50 40|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K70 1cL0 1cN0 1fz0 1cN0 1cL0 3Cp0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|11e4", 12697 "America/Vancouver|PST PDT|80 70|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|Ka0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|23e5", 12698 "America/Whitehorse|PST PDT|80 70|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|p7K0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|23e3", 12699 "America/Winnipeg|CST CDT|60 50|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K80 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1a00 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1a00 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 14o0 1lc0 14o0 1o00 11A0 1o00 11A0 1o00 14o0 1lc0 14o0 1lc0 14o0 1o00 11A0 1o00 11A0 1o00 14
12699o0 1lc0 14o0 1lc0 14o0 1lc0 14o0 1o00 11A0 1o00 11A0 1o00 14o0 1lc0 14o0 1lc0 14o0 1o00 11A0 1o00 11A0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|66e4", 12700 "America/Yakutat|YST YDT AKST AKDT|90 80 90 80|0101010101010101010101010101023232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|Kb0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 cn0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|642", 12701 "America/Yellowknife|MST MDT|70 60|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|p7J0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|19e3", 12702 "Antarctica/Casey|+08 +11|-80 -b0|0101010|1ARS0 T90 40P0 KL0 blz0 3m10|10", 12703 "Antarctica/Davis|+07 +05|-70 -50|01010|1ART0 VB0 3Wn0 KN0|70", 12704 "Pacific/Port_Moresby|+10|-a0|0||25e4", 12705 "Antarctica/Macquarie|AEDT AEST +11|-b0 -a0 -b0|0101010101010101010101010101010101010101010101010101010101010101010101010101010102|qg0 1wo0 U00 1wo0 LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 11A0 1qM0 WM0 1qM0 Oo0 1zc0 Oo0 1zc0 Oo0 1wo0 WM0 1tA0 WM0 1tA0 U00 1tA0 U00 1tA0 11A0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 11A0 1o00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1cM0 1a00 1io0 1cM0 1cM0 1cM0 1cM0 1cM0|1", 12706 "Antarctica/Mawson|+06 +05|-60 -50|01|1ARU0|60", 12707 "Pacific/Auckland|NZST NZDT|-c0 -d0|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|bKC0 IM0 1C00 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1qM0 14o0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1io0 17c0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1io0 17c0 1io0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00|14e5", 12708 "Antarctica/Palmer|-03 -02 -04|30 20 40|010202020202
1270802020202020202020202020202020202020202020202020202020202020|9Rf0 Db0 jsN0 14N0 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 1cL0 1cN0 11z0 1o10 11z0 1qN0 WL0 1fB0 19X0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1ip0 1fz0 1fB0 11z0 1qN0 WL0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1o10 19X0 1fB0 1nX0 G10 1EL0 Op0 1zb0 Rd0 1wn0 Rd0 46n0 Ap0|40", 12709 "Antarctica/Rothera|-00 -03|0 30|01|gOo0|130", 12710 "Asia/Riyadh|+03|-30|0||57e5", 12711 "Antarctica/Troll|-00 +00 +02|0 0 -20|012121212121212121212121212121212121212121212121212121|1puo0 hd0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|40", 12712 "Asia/Urumqi|+06|-60|0||32e5", 12713 "Europe/Berlin|CET CEST|-10 -20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|oXd0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|41e5", 12714 "Asia/Almaty|+06 +07 +05|-60 -70 -50|0101010101010101010102010101010101010101010101010|rn60 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0|15e5", 12715 "Asia/Amman|EET EEST|-20 -30|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|8kK0 KL0 1oN0 11b0 1oN0 11b0 1pd0 1dz0 1cp0 11b0 1op0 11b0 fO10 1db0 1e10 1cL0 1cN0 1cL0 1cN0 1fz0 1pd0 10n0 1ld0 14n0 1hB0 15b0 1ip0 19X0 1cN0 1cL0 1cN0 17b0 1ld0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1So0 y00 1fc0 1dc0 1co0 1dc0 1cM0 1cM0 1cM0 1o00 11A0 1lc0 17c0 1cM0 1cM0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 4bX0 Dd0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|25e5", 12716 "Asia/Anadyr|+13 +14 +12 +11|-d0 -e0 -c0 -b0|010202020202
12716020202023202020202020202020202020202020202020232|rmX0 1db0 2q10 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 2sp0 WM0|13e3", 12717 "Asia/Aqtau|+05 +06 +04|-50 -60 -40|0101010101010101010201010120202020202020202020|sAj0 2pX0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0|15e4", 12718 "Asia/Aqtobe|+05 +06 +04|-50 -60 -40|01010101010101010102010101010101010101010101010|rn70 3Db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0|27e4", 12719 "Asia/Ashgabat|+05 +06 +04|-50 -60 -40|01010101010101010101020|rn70 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0|41e4", 12720 "Asia/Atyrau|+05 +06 +04|-50 -60 -40|010101010101010101020101010101010102020202020|sAj0 2pX0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 2sp0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0", 12721 "Asia/Baghdad|+03 +04|-30 -40|01010101010101010101010101010101010101010101010101010|u190 11b0 1cp0 1dz0 1dd0 1db0 1cN0 1cp0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1de0 1dc0 1dc0 1dc0 1cM0 1dc0 1cM0 1dc0 1cM0 1dc0 1dc0 1dc0 1cM0 1dc0 1cM0 1dc0 1cM0 1dc0 1dc0 1dc0 1cM0 1dc0 1cM0 1dc0 1cM0 1dc0 1dc0 1dc0 1cM0 1dc0 1cM0 1dc0 1cM0 1dc0|66e5", 12722 "Asia/Qatar|+04 +03|-40 -30|01|5QI0|96e4", 12723 "Asia/Baku|+04 +05 +03|-40 -50 -30|010101010101010101010201010101010101010101010101010101010101010|rn80 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 1cM0 9Je0 1o00 11z0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|27e5", 12724 "Asia/Bangkok|+07|-70|0||15e6", 12725 "Asia/Barnaul|+07 +08 +06|-70 -80 -60|01010101010101010101020101010102020202020202020202020202020202020|rn50 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 p90 LE0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3rd0", 12726 "Asia/Beirut|EET EEST|-20 -30|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|61a0 En0 1oN0 11b0 1oN0 11b0 1oN0 11b0 1pd0 11b0 1oN0 11b0 1op0 11b0 dA10 17b0 1iN0 17b0 1iN0 17b0 1iN0 17b0 1vB0 SL0 1mp0 13z0 1iN0 17b0 1iN0 17b0 1jd0 12n0 1a10 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0|22e5", 12727 "Asia/Bishkek|+06 +07 +05|-60 -70 -50|0101010101010101010102020202020202020202020202020|rn60 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2e00 1tX0 17b0 1ip0 17b0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1cPu 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0|87e4", 12728 "Asia/Brunei|+08|-80|0||42e4", 12729 "Asia/Kolkata|IST|-5u|0||15e6", 12730 "Asia/Chita|+09 +10 +08|-90 -a0 -80|0101010101010101010102010101010101010101010101010101010101010120|rn30 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3re0|33e4", 12731 "Asia/Choibalsan|+07 +08 +10 +09|-70 -80 -a0 -90|012323232323232323232323232323232323232323232313131|jsF0 cKn0 1da0 1dd0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 6hD0 11z0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 3Db0 h1f0 1cJ0 1cP0 1cJ0|38e3", 12732 "Asia/Shanghai|CST CDT|-80 -90|0101010101010|DKG0 Rb0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0|23e6", 12733 "Asia/Colombo|+0530 +0630 +06|-5u -6u -60|0120|14giu 11zu n3cu|22e5", 12734 "Asia/Dhaka|+06 +07|-60 -70|010|1A5R0 1i00|16e6", 12735 "Asia/Damascus|EET EEST|-20 -30|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|M00 11b0 1oN0 11b0 1pd0 11b0 1oN0 11b0 1oN0 11b0 1oN0 11b0 1pd0 11b0 1oN0 Nb0 1AN0 Nb0 bcp0 19X0 1gp0 19X0 3ld0 1xX0 Vd0 1Bz0 Sp0 1vX0 10p0 1dz0 1cN0 1cL0 1db0 1db0 1g10 1an0 1ap0 1db0 1fd0 1db0 1cN0 1db0 1dd0 1db0 1cp0 1dz0 1c10 1dX0 1cN0 1db0 1dd0 1db0 1cN0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1db0 1cN0 1db0 1cN0 19z0 1fB0 1qL0 11B0 1on0 Wp0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0|26e5", 12736 "Asia/Dili|+09 +08|-90 -80|010|fpr0 Xld0|19e4", 12737 "Asia/Dubai|+04|-40|0||39e5", 12738 "Asia/Dushanbe|+06 +07 +05|-60 -70 -50|0101010101010101010102|rn60 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2hB0|76e4", 12739 "Asia/Famagusta|EET EEST +03|-20 -30 -30|0101010101010101010101010101010101010101010101010101010101010101010101010101010101012010101010101010101010101010|cPa0 1cL0 1qp0 Xz0 19B0 19X0 1fB0 1db0 1cp0 1cL0 1fB0 19X0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1o30 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 15U0 2Ks0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00", 12740 "Asia/Gaza|IST IDT EET EEST|-20 -30 -20 -30|010101010101010101010101010101023232323232323232323232323232323232323232323232323232323232323232323232|aXa0 Db0 1fB0 Rb0 bXd0 gM0 8Q00 IM0 1wM0 11z0 1C10 IL0 1s10 10n0 1o10 WL0 1zd0 On0 1ld0 11z0 1o10 14n0 1o10 14n0 1nd0 12n0 1nd0 Xz0 1q10 12n0 M10 C00 17c0 1io0 17c0 1io0 17c0 1o00 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 17c0 1io0 18
12740N0 1bz0 19z0 1gp0 1610 1iL0 11z0 1o10 14o0 1lA1 SKX 1xd1 MKX 1AN0 1a00 1fA0 1cL0 1cN0 1nX0 1210 1nz0 1220 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0|18e5", 12741 "Asia/Hebron|IST IDT EET EEST|-20 -30 -20 -30|01010101010101010101010101010102323232323232323232323232323232323232323232323232323232323232323232323232|aXa0 Db0 1fB0 Rb0 bXd0 gM0 8Q00 IM0 1wM0 11z0 1C10 IL0 1s10 10n0 1o10 WL0 1zd0 On0 1ld0 11z0 1o10 14n0 1o10 14n0 1nd0 12n0 1nd0 Xz0 1q10 12n0 M10 C00 17c0 1io0 17c0 1io0 17c0 1o00 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 17c0 1io0 18N0 1bz0 19z0 1gp0 1610 1iL0 12L0 1mN0 14o0 1lc0 Tb0 1xd1 MKX bB0 cn0 1cN0 1a00 1fA0 1cL0 1cN0 1nX0 1210 1nz0 1220 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0|25e4", 12742 "Asia/Ho_Chi_Minh|+08 +07|-80 -70|01|dfs0|90e5", 12743 "Asia/Hong_Kong|HKT HKST|-80 -90|01010101010101010|H7u 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 s10 1Vz0 1cN0 1cL0 1cN0 1cL0 6fd0 14n0|73e5", 12744 "Asia/Hovd|+06 +07 +08|-60 -70 -80|01212121212121212121212121212121212121212121212121|jsG0 cKn0 1db0 1dd0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 6hD0 11z0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 kEp0 1cJ0 1cP0 1cJ0|81e3", 12745 "Asia/Irkutsk|+08 +09 +07|-80 -90 -70|010101010101010101010201010101010101010101010101010101010101010|rn40 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|60e4", 12746 "Europe/Istanbul|EET EEST +04 +03|-20 -30 -40 -30|01010101010101010123232323231010101010101010101010101010101010101010101010101010101010101013|MK0 11z0 1o10 11z0 1qN0 11z0 1ze0 11B0 WM0 1qO0 WI0 1nX0 1rB0 10L0 11B0 1in0 17d0 1in0 2pX0 19E0 1fU0 16Q0 1iI0 16Q0 1iI0 1Vd0 pb0 3Kp0 14o0 1de0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1a00 1fA0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WO0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 Xc0 1qo0 WM0 1qM0 11A0 1o00 1200 1nA0 11A0 1tA0 U00 15w0|13e6", 12747 "Asia/Jakarta|WIB|-70|0||31e6", 12748 "Asia/Jayapura|WIT|-90|0||26e4", 12749 "Asia/Jerusalem|IST IDT|-20 -30|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|aXa0 Db0 1fB0 Rb0 bXd0 gM0 8Q00 IM0 1wM0 11z0 1C10 IL0 1s10 10n0 1o10 WL0 1zd0 On0 1ld0 11z0 1o10 14n0 1o10 14n0 1nd0 12n0 1nd0 Xz0 1q10 12n0 1hB0 1dX0 1ep0 1aL0 1eN0 17X0 1nf0 11z0 1tB0 19W0 1e10 17b0 1ep0 1gL0 18N0 1fz0 1eN0 17b0 1gq0 1gn0 19d0 1dz0 1c10 17X0 1hB0 1gn0 19d0 1dz0 1c10 17X0 1kp0 1dz0 1c10 1aL0 1eN0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0|81e4", 12750 "Asia/Kabul|+0430|-4u|0||46e5", 12751 "Asia/Kamchatka|+12 +13 +11|-c0 -d0 -b0|0101010101010101010102010101010101010101010101010101010101020|rn00 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 2sp0 WM0|18e4", 12752 "Asia/Karachi|+05 PKT PKST|-50 -50 -60|01212121|2Xv0 1fy00 1cL0 dK10 11b0 1610 1jX0|24e6", 12753 "Asia/Kathmandu|+0530 +0545|-5u -5J|01|CVuu|12e5", 12754 "Asia/Khandyga|+09 +10 +08 +11|-90 -a0 -80 -b0|01010101010101010101020101010101010101010101010131313131313131310|rn30 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 qK0 yN0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 17V0 7zD0|66e2", 12755 "Asia/Krasnoyarsk|+07 +08 +06|-70 -80 -60|010101010101010101010201010101010101010101010101010101010101010|rn50 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|10e5", 12756 "Asia/Kuala_Lumpur|+0730 +08|-7u -80|01|td4u|71e5", 12757 "Asia/Macau|CST CDT|-80 -90|01010101010101010|H7u 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 s10 1Vz0 1cN0 1cL0 1cN0 1cL0 6fd0 14n0|57e4", 12758 "Asia/Magadan|+11 +12 +10|-b0 -c0 -a0|0101010101010101010102010101010101010101010101010101010101010120|rn10 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3Cq0|95e3", 12759 "Asia/Makassar|WITA|-80|0||15e5", 12760 "Asia/Manila|PST PDT|-80 -90|010|k0E0 1db0|24e6", 12761 "Asia/Nicosia|EET EEST|-20 -30|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|cPa0 1cL0 1qp0 Xz0 19B0 19X0 1fB0 1db0 1cp0 1cL0 1fB0 19X0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1o30 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|32e4", 12762 "Asia/Novokuznetsk|+07 +08 +06|-70 -80 -60|0101010101010101010102010101010101010101010101010101010101020|rn50 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 2sp0 WM0|55e4", 12763 "Asia/Novosibirsk|+07 +08 +06|-70 -80 -60|010101010101010101010201010202020202
1276302020202020202020202020202020|rn50 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 ml0 Os0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 4eN0|15e5", 12764 "Asia/Omsk|+06 +07 +05|-60 -70 -50|010101010101010101010201010101010101010101010101010101010101010|rn60 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|12e5", 12765 "Asia/Oral|+05 +06 +04|-50 -60 -40|010101010101010202020202020202020202020202020|rn70 3Db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 2pB0 1cM0 1fA0 1cM0 1cM0 IM0 1EM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0|27e4", 12766 "Asia/Pontianak|WITA WIB|-80 -70|01|HNs0|23e4", 12767 "Asia/Pyongyang|KST KST|-90 -8u|010|1P4D0 6BA0|29e5", 12768 "Asia/Qostanay|+05 +06 +04|-50 -60 -40|0101010101010101010201010101010101010101010101|rn70 3Db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0", 12769 "Asia/Qyzylorda|+05 +06|-50 -60|010101010101010101010101010101010101010101010|rn70 3Db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 3ao0 1EM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 zQl0|73e4", 12770 "Asia/Rangoon|+0630|-6u|0||48e5", 12771 "Asia/Sakhalin|+11 +12 +10|-b0 -c0 -a0|010101010101010101010201010101010202020202020202020202020202020|rn10 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 2pB0 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3rd0|58e4", 12772 "Asia/Samarkand|+05 +06|-50 -60|010101010101010101010|rn70 3Db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0|36e4", 12773 "Asia/Seoul|KST KDT|-90 -a0|01010|Gf50 11A0 1o00 11A0|23e6", 12774 "Asia/Srednekolymsk|+11 +12 +10|-b0 -c0 -a0|010101010101010101010201010101010101010101010101010101010101010|rn10 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|35e2", 12775 "Asia/Taipei|CST CDT|-80 -90|0101010|akg0 1db0 1cN0 1db0 97B0 AL0|74e5", 12776 "Asia/Tashkent|+06 +07 +05|-60 -70 -50|0101010101010101010102|rn60 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0|23e5", 12777 "Asia/Tbilisi|+04 +05 +03|-40 -50 -30|01010101010101010101020202010101010101010101020|rn80 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 1cK0 1cL0 1cN0 1cL0 1cN0 2pz0 1cL0 1fB0 3Nz0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 An0 Os0 WM0|11e5", 12778 "Asia/Tehran|+0330 +04 +05 +0430|-3u -40 -50 -4u|0121030303030303030303030303030303030303030303030303030303030303030303030303030303030|j4ku TXu 1pz0 sN0 vAu 1cL0 1dB0 1en0 pNB0 UL0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 64p0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0|14e6", 12779 "Asia/Thimphu|+0530 +06|-5u -60|01|HcGu|79e3", 12780 "Asia/Tokyo|JST|-90|0||38e6", 12781 "Asia/Tomsk|+07 +08 +06|-70 -80 -60|010101010101010101010201010101010101010101010202020202
1278102020202020|rn50 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 co0 1bB0 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3Qp0|10e5", 12782 "Asia/Ulaanbaatar|+07 +08 +09|-70 -80 -90|01212121212121212121212121212121212121212121212121|jsF0 cKn0 1db0 1dd0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 6hD0 11z0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 kEp0 1cJ0 1cP0 1cJ0|12e5", 12783 "Asia/Ust-Nera|+09 +12 +11 +10|-90 -c0 -b0 -a0|0121212121212121212123212121212121212121212121212121212121212123|rn30 1d90 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 17V0 7zD0|65e2", 12784 "Asia/Vladivostok|+10 +11 +09|-a0 -b0 -90|010101010101010101010201010101010101010101010101010101010101010|rn20 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|60e4", 12785 "Asia/Yakutsk|+09 +10 +08|-90 -a0 -80|010101010101010101010201010101010101010101010101010101010101010|rn30 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|28e4", 12786 "Asia/Yekaterinburg|+05 +06 +04|-50 -60 -40|010101010101010101010201010101010101010101010101010101010101010|rn70 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|14e5", 12787 "Asia/Yerevan|+04 +05 +03|-40 -50 -30|01010101010101010101020202020101010101010101010101010101010|rn80 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 4RX0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|13e5", 12788 "Atlantic/Azores|-01 +00 WET|10 0 0|0101010101010101010101010101010121010101010101010101010101010101010101010101010101010101010101010101010101010|hAN0 1cM0 1fA0 1cM0 1cM0 1cN0 1cL0 1cN0 1cM0 1cM0 1cM0 1cM0 1cN0 1cL0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cL0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|25e4", 12789 "Atlantic/Bermuda|AST ADT|40 30|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|avi0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|65e3",
12790 "Atlantic/Canary|WET WEST|0 -10|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|oXc0 1a10 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|54e4", 12791 "Atlantic/Cape_Verde|-02 -01|20 10|01|elE0|50e4", 12792 "Atlantic/Faroe|WET WEST|0 -10|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|rm10 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|49e3", 12793 "Atlantic/Madeira|WET WEST|0 -10|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|hAM0 1cM0 1fA0 1cM0 1cM0 1cN0 1cL0 1cN0 1cM0 1cM0 1cM0 1cM0 1cN0 1cL0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|27e4", 12794 "Atlantic/South_Georgia|-02|20|0||30", 12795 "Atlantic/Stanley|-04 -03 -02|40 30 20|01212101010101010101010101010101010101010101010101010101|wrg0 WL0 1qL0 U10 1tz0 2mN0 WN0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1tz0 U10 1tz0 WN0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1tz0 WN0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qN0 U10 1wn0 Rd0 1wn0 U10 1tz0 U10 1tz0 U10 1tz0 U10 1tz0 U10 1wn0 U10 1tz0 U10 1tz0 U10|21e2", 12796 "Australia/Sydney|AEST AEDT|-a0 -b0|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|4r40 LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 14o0 1o00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 U00 1qM0 WM0 1tA0 WM0 1tA0 U00 1tA0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 11A0 1o00 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 WM0 1qM0 14o0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0|40e5", 12797 "Australia/Adelaide|ACST ACDT|-9u -au|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|4r4u LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 U00 1qM0 WM0 1tA0 WM0 1tA0 U00 1tA0 U00 1tA0 Oo0 1zc0 WM0 1qM0 Rc0 1zc0 U00 1tA0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 WM0 1qM0 14o0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0|11e5", 12798 "Australia/Brisbane|AEST AEDT|-a0 -b0|010101010|4r40 LA0 H1A0 Oo0 1zc0 Oo0 1zc0 Oo0|20e5", 12799 "Australia/Broken_Hill|ACST ACDT|-9u -au|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|4r4u LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 14o0 1o00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 U00 1qM0 WM0 1tA0 WM0 1tA0 U00 1tA0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 WM0 1qM0 14o0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0|18e3", 12800 "Australia/Currie|AEST AEDT|-a0 -b0|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|4r40 LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 11A0 1qM0 WM0 1qM0 Oo0 1zc0 Oo0 1zc0 Oo0 1wo0 WM0 1tA0 WM0 1tA0 U00 1tA0 U00 1tA0 11A0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 11A0 1o00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1cM0 1a00 1io0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0|746", 12801 "Australia/Darwin|ACST|-9u|0||12e4", 12802 "Australia/Eucla|+0845 +0945|-8J -9J|0101010101010|bHRf Oo0 l5A0 Oo0 iJA0 G00 zU00 IM0 1qM0 11A0 1o00 11A0|368", 12803 "Australia/Hobart|AEDT AEST|-b0 -a0|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|qg0 1wo0 U00 1wo0 LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 11A0 1qM0 WM0 1qM0 Oo0 1zc0 Oo0 1zc0 Oo0 1wo0 WM0 1tA0 WM0 1tA0 U00 1tA0 U00 1tA0 11A0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 11A0 1o00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1cM0 1a00 1io0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0|21e4", 12804 "Australia/Lord_Howe|AEST +1030 +1130 +11|-a0 -au -bu -b0|01212121213131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313|raC0 1zdu Rb0 1zd0 On0 1zd0 On0 1zd0 On0 1zd0 TXu 1qMu WLu 1tAu WLu 1tAu TXu 1tAu Onu 1zcu Onu 1zcu Onu 1zcu Rbu 1zcu Onu 1zcu Onu 1zcu 11zu 1o0u 11zu 1o0u 11zu 1o0u 11zu 1qMu WLu 11Au 1nXu 1qMu 11zu 1o0u 11zu 1o0u 11zu 1qMu WLu 1qMu 11zu 1o0u WLu 1qMu 14nu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1fzu 1cMu
128041cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu|347", 12805 "Australia/Lindeman|AEST AEDT|-a0 -b0|0101010101010|4r40 LA0 H1A0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0|10", 12806 "Australia/Melbourne|AEST AEDT|-a0 -b0|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|4r40 LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 U00 1qM0 WM0 1qM0 11A0 1tA0 U00 1tA0 U00 1tA0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 11A0 1o00 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 WM0 1qM0 14o0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0|39e5", 12807 "Australia/Perth|AWST AWDT|-80 -90|0101010101010|bHS0 Oo0 l5A0 Oo0 iJA0 G00 zU00 IM0 1qM0 11A0 1o00 11A0|18e5", 12808 "Europe/Brussels|CET CEST|-10 -20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|hDB0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|21e5", 12809 "Pacific/Easter|-06 -07 -05|60 70 50|010101010101010101010101020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202|yP0 1ip0 11z0 1o10 11z0 1qN0 WL0 1ld0 14n0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 2pA0 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 1cL0 1cN0 11z0 1o10 11z0 1qN0 WL0 1fB0 19X0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1ip0 1fz0 1fB0 11z0 1qN0 WL0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1o10 19X0 1fB0 1nX0 G10 1EL0 Op0 1zb0 Rd0 1wn0 Rd0 46n0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1zb0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0|30e2", 12810 "EET|EET EEST|-20 -30|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|hDB0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00", 12811 "Europe/Dublin|IST GMT|-10 0|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|4re0 U00 1tA0 U00 1tA0 U00 1tA0 U00 1tA0 WM0 1qM0 WM0 1qM0 WM0 1tA0 U00 1tA0 U00 1tA0 11z0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 14o0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|12e5", 12812 "Etc/GMT-1|+01|-10|0|", 12813 "Pacific/Guadalcanal|+11|-b0|0||11e4", 12814 "Pacific/Tarawa|+12|-c0|0||29e3", 12815 "Etc/GMT-13|+13|-d0|0|", 12816 "Etc/GMT-14|+14|-e0|0|", 12817 "Etc/GMT-2|+02|-20|0|", 12818 "Indian/Maldives|+05|-50|0||35e4", 12819 "Pacific/Palau|+09|-90|0||21e3",
12820 "Etc/GMT+1|-01|10|0|", 12821 "Pacific/Tahiti|-10|a0|0||18e4", 12822 "Etc/GMT+11|-11|b0|0|", 12823 "Etc/GMT+12|-12|c0|0|", 12824 "Etc/GMT+5|-05|50|0|", 12825 "Etc/GMT+6|-06|60|0|", 12826 "Etc/GMT+7|-07|70|0|", 12827 "Etc/GMT+8|-08|80|0|", 12828 "Pacific/Gambier|-09|90|0||125", 12829 "Etc/UTC|UTC|0|0|", 12830 "Europe/Andorra|CET CEST|-10 -20|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|B7d0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|79e3", 12831 "Europe/Astrakhan|+04 +05 +03|-40 -50 -30|0101010101010101020202020202020202020202020202020202020202020|rn80 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 2pB0 1cM0 1fA0 1cM0 3Co0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3rd0|10e5", 12832 "Europe/Athens|EET EEST|-20 -30|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|cOK0 1vc0 SO0 1cM0 1a00 1ao0 1fc0 1a10 1fG0 1cg0 1dX0 1bX0 1cQ0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|35e5", 12833 "Europe/London|BST GMT|-10 0|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|4re0 U00 1tA0 U00 1tA0 U00 1tA0 U00 1tA0 WM0 1qM0 WM0 1qM0 WM0 1tA0 U00 1tA0 U00 1tA0 11z0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 14o0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|10e6", 12834 "Europe/Belgrade|CET CEST|-10 -20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|wdd0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|12e5", 12835 "Europe/Prague|CET CEST|-10 -20|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|muN0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|13e5", 12836 "Europe/Bucharest|EET EEST|-20 -30|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|mRa0 On0 1fA0 1a10 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cK0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cL0 1cN0 1cL0 1fB0 1nX0 11E0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|19e5", 12837 "Europe/Budapest|CET CEST|-10 -20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|oXc0 1a10 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|17e5", 12838 "Europe/Zurich|CET CEST|-10 -20|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|rm10 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|38e4", 12839 "Europe/Chisinau|MSK MSD EEST EET|-30 -40 -30 -20|010101010101010101012323232323232323232323232323232323232323232323232323232323232323232323232323232323|rn90 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 gL0 WO0 1cM0 1cM0 1cK0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1nX0 11D0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|67e4", 12840 "Europe/Gibraltar|CET CEST|-10 -20|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|tLB0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|30e3", 12841 "Europe/Helsinki|EET EEST|-20 -30|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|rm00 1cM0 1cM0 1cM0 1cN0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|12e5", 12842 "Europe/Kaliningrad|MSK MSD EEST EET +03|-30 -40 -30 -20 -30|010101010101010102323232323232323232323232323232323232323232343|rn90 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|44e4", 12843 "Europe/Kiev|MSK MSD EEST EET|-30 -40 -30 -20|0101010101010101010123232323232323232323232323232323232323232323232323232323232323232323232323232323|rn90 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 Db0 3220 1cK0 1cL0 1cN0 1cL0 1cN0 1cL0 1cQ0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|34e5", 12844 "Europe/Kirov|+04 +05 +03|-40 -50 -30|01010101010101010202020202
128440202020202020202020202020202020202|rn80 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 2pB0 1cM0 1fA0 1cM0 3Co0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|48e4", 12845 "Europe/Lisbon|CET WET WEST CEST|-10 0 -10 -20|01212121212121212121212121212121203030302121212121212121212121212121212121212121212121212121212121212121212121|go00 1cM0 1cM0 1fA0 1cM0 1cM0 1cN0 1cL0 1cN0 1cM0 1cM0 1cM0 1cM0 1cN0 1cL0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|27e5", 12846 "Europe/Madrid|CET CEST|-10 -20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|apy0 1a10 1fz0 1a10 19X0 1cN0 1fz0 1a10 1fC0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|62e5", 12847 "Europe/Malta|CET CEST|-10 -20|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|XX0 LA0 1zc0 Oo0 1C00 Oo0 1co0 1cM0 1lA0 Xc0 1qq0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1iN0 19z0 1fB0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|42e4", 12848 "Europe/Minsk|MSK MSD EEST EET +03|-30 -40 -30 -20 -30|010101010101010101023232323232323232323232323232323232323234|rn90 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 3Fc0 1cN0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0|19e5", 12849 "Europe/Paris|CET CEST|-10 -20|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|fbc0 1cL0 1fC0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|11e6", 12850 "Europe/Moscow|MSK MSD EEST EET MSK|-30 -40 -30 -20 -40|0101010101010101010102301010101010101010101010101010101010101040|rn90 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cN0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|16e6", 12851 "Europe/Riga|MSK MSD EEST EET|-30 -40 -30 -20|010101010101010102323232323232323232323232323232323232323232323232323232323232323232323232323232323|rn90 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cN0 1o00 11A0 1o00 11A0 1qM0 3oo0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|64e4", 12852 "Europe/Rome|CET CEST|-10 -20|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|XX0 LA0 1zc0 Oo0 1C00 Oo0 1C00 LA0 1zc0 Oo0 1C00 LA0 1C00 LA0 1zc0 Oo0 1C00 Oo0 1zc0 Oo0 1fC0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|39e5", 12853 "Europe/Samara|+04 +05 +03|-40 -50 -30|01010101010101010202010101010101010101010101010101010101020|rn80 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 2pB0 1cM0 1fA0 2y10 14m0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 2sp0 WM0|12e5", 12854 "Europe/Saratov|+04 +05 +03|-40 -50 -30|010101010101010202020202
128540202020202020202020202020202020202020|rn80 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 2pB0 1cM0 1cM0 1cM0 1fA0 1cM0 3Co0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 5810", 12855 "Europe/Simferopol|MSK MSD EET EEST MSK|-30 -40 -20 -30 -40|0101010101010101010232323101010323232323232323232323232323232323240|rn90 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1Q00 4eL0 1cL0 1cN0 1cL0 1cN0 dX0 WL0 1cN0 1cL0 1fB0 1o30 11B0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11z0 1nW0|33e4", 12856 "Europe/Sofia|EET EEST|-20 -30|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|muJ0 1dd0 1fb0 1ap0 1fb0 1a20 1fy0 1a30 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cK0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1nX0 11E0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|12e5", 12857 "Europe/Tallinn|MSK MSD EEST EET|-30 -40 -30 -20|0101010101010101023232323232323232323232323232323232323232323232323232323232323232323232323232323|rn90 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o10 11A0 1qM0 5QM0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|41e4", 12858 "Europe/Tirane|CET CEST|-10 -20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|axz0 10n0 1op0 11z0 1pd0 11z0 1qN0 WL0 1qp0 Xb0 1qp0 Xb0 1qp0 11z0 1lB0 11z0 1qN0 11z0 1iN0 16n0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|42e4", 12859 "Europe/Ulyanovsk|+04 +05 +03 +02|-40 -50 -30 -20|010101010101010102023202020202020202020202020202020202020202020|rn80 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 2pB0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3rd0|13e5", 12860 "Europe/Uzhgorod|MSK MSD CET EET EEST|-30 -40 -10 -20 -30|010101010101010101023434343434343434343434343434343434343434343434343434343434343434343434343434343|rn90 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1Q00 1Nf0 2pw0 1cL0 1cN0 1cL0 1cN0 1cL0 1cQ0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|11e4", 12861 "Europe/Vienna|CET CEST|-10 -20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|oXb0 19X0 1cP0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|18e5", 12862 "Europe/Vilnius|MSK MSD EEST EET CEST CET|-30 -40 -30 -20 -20 -10|01010101010101010232323232323232323454323232323232323232323232323232323232323232323232323232323|rn90 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11B0 1o00 11A0 1qM0 8io0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|54e4", 12863 "Europe/Volgograd|+04 +05 +03|-40 -50 -30|010101010101010202020202
128630202020202020202020202020202020202020|rn80 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 2pB0 1cM0 1cM0 1cM0 1fA0 1cM0 3Co0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 9Jd0|10e5", 12864 "Europe/Warsaw|CET CEST|-10 -20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|hDA0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|17e5", 12865 "Europe/Zaporozhye|MSK MSD EEST EET|-30 -40 -30 -20|01010101010101010101023232323232323232323232323232323232323232323232323232323232323232323232323232323|rn90 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cK0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cQ0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|77e4", 12866 "Pacific/Honolulu|HST|a0|0||37e4", 12867 "Indian/Chagos|+05 +06|-50 -60|01|13ij0|30e2", 12868 "Indian/Mauritius|+04 +05|-40 -50|01010|v5U0 14L0 12kr0 11z0|15e4", 12869 "Pacific/Kwajalein|-12 +12|c0 -c0|01|Vxo0|14e3", 12870 "MET|MET MEST|-10 -20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|hDB0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00", 12871 "Pacific/Chatham|+1245 +1345|-cJ -dJ|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|bKC0 IM0 1C00 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1qM0 14o0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1io0 17c0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1io0 17c0 1io0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00|600", 12872 "Pacific/Apia|-11 -10 +14 +13|b0 a0 -e0 -d0|0101232323232323232323232323232323232323232|1Dbn0 1ff0 1a00 CI0 AQ0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00|37e3", 12873 "Pacific/Bougainville|+10 +11|-a0 -b0|01|1NwE0|18e4", 12874 "Pacific/Efate|+11 +12|-b0 -c0|010101010101010101010|xpN0 1cL0 1oN0 10L0 1fB0 19X0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 Lz0 1Nd0 An0|66e3", 12875 "Pacific/Enderbury|-12 -11 +13|c0 b0 -d0|012|nIc0 B7X0|1", 12876 "Pacific/Fakaofo|-11 +13|b0 -d0|01|1Gfn0|483", 12877 "Pacific/Fiji|+12 +13|-c0 -d0|010101010101010101010101010101010101010101010101|1ace0 LA0 1EM0 IM0 nJc0 LA0 1o00 Rc0 1wo0 Ao0 1Nc0 Ao0 1Q00 xz0 1SN0 uM0 1SM0 uM0 1VA0 s00 1VA0 s00 1VA0 s00 1VA0 uM0 1SM0 uM0 1VA0 s00 1VA0 s00 1VA0 s00 1VA0 uM0 1SM0 uM0 1SM0 uM0 1VA0 s00 1VA0 s00 1VA0 s00 1VA0|88e4", 12878 "Pacific/Galapagos|-05 -06|50 60|0101|CVF0 gNd0 rz0|25e3", 12879 "Pacific/Guam|GST GDT ChST|-a0 -b0 -a0|010101010102|JQ0 Rb0 1wp0 Rb0 5xd0 rX0 5sN0 zb1 1C0X On0 ULb0|17e4",
12880 "Pacific/Kiritimati|-1040 -10 +14|aE a0 -e0|012|nIaE B7Xk|51e2", 12881 "Pacific/Kosrae|+12 +11|-c0 -b0|01|1aAA0|66e2", 12882 "Pacific/Marquesas|-0930|9u|0||86e2", 12883 "Pacific/Pago_Pago|SST|b0|0||37e2", 12884 "Pacific/Nauru|+1130 +12|-bu -c0|01|maCu|10e3", 12885 "Pacific/Niue|-1130 -11|bu b0|01|libu|12e2", 12886 "Pacific/Norfolk|+1130 +1230 +11|-bu -cu -b0|0102|bHOu On0 1COp0|25e4", 12887 "Pacific/Noumea|+11 +12|-b0 -c0|0101010|jhp0 xX0 1PB0 yn0 HeP0 Ao0|98e3", 12888 "Pacific/Pitcairn|-0830 -08|8u 80|01|18Vku|56", 12889 "Pacific/Rarotonga|-1030 -0930 -10|au 9u a0|012121212121212121212121212|lyWu IL0 1zcu Onu 1zcu Onu 1zcu Rbu 1zcu Onu 1zcu Onu 1zcu Onu 1zcu Onu 1zcu Onu 1zcu Rbu 1zcu Onu 1zcu Onu 1zcu Onu|13e3", 12890 "Pacific/Tongatapu|+13 +14|-d0 -e0|010101010|1csd0 15A0 1wo0 xz0 1Q10 xz0 zWN0 s00|75e3", 12891 "WET|WET WEST|0 -10|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|hDB0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00" 12892 ], 12893 "links": [ 12894 "Africa/Abidjan|Africa/Accra", 12895 "Africa/Abidjan|Africa/Bamako", 12896 "Africa/Abidjan|Africa/Banjul", 12897 "Africa/Abidjan|Africa/Conakry", 12898 "Africa/Abidjan|Africa/Dakar", 12899 "Africa/Abidjan|Africa/Freetown", 12900 "Africa/Abidjan|Africa/Lome", 12901 "Africa/Abidjan|Africa/Nouakchott", 12902 "Africa/Abidjan|Africa/Ouagadougou", 12903 "Africa/Abidjan|Africa/Timbuktu", 12904 "Africa/Abidjan|Atlantic/Reykjavik", 12905 "Africa/Abidjan|Atlantic/St_Helena", 12906 "Africa/Abidjan|Etc/GMT", 12907 "Africa/Abidjan|Etc/GMT+0", 12908 "Africa/Abidjan|Etc/GMT-0", 12909 "Africa/Abidjan|Etc/GMT0", 12910 "Africa/Abidjan|Etc/Greenwich", 12911 "Africa/Abidjan|GMT", 12912 "Africa/Abidjan|GMT+0", 12913 "Africa/Abidjan|GMT-0", 12914 "Africa/Abidjan|GMT0", 12915 "Africa/Abidjan|Greenwich", 12916 "Africa/Abidjan|Iceland", 12917 "Africa/Cairo|Egypt", 12918 "Africa/Johannesburg|Africa/Maseru", 12919 "Africa/Johannesburg|Africa/Mbabane", 12920 "Africa/Lagos|Africa/Bangui", 12921 "Africa/Lagos|Africa/Brazzaville", 12922 "Africa/Lagos|Africa/Douala", 12923 "Africa/Lagos|Africa/Kinshasa", 12924 "Africa/Lagos|Africa/Libreville", 12925 "Africa/Lagos|Africa/Luanda", 12926 "Africa/Lagos|Africa/Malabo", 12927 "Africa/Lagos|Africa/Niamey", 12928 "Africa/Lagos|Africa/Porto-Novo", 12929 "Africa/Maputo|Africa/Blantyre", 12930 "Africa/Maputo|Africa/Bujumbura", 12931 "Africa/Maputo|Africa/Gaborone", 12932 "Africa/Maputo|Africa/Harare", 12933 "Africa/Maputo|Africa/Kigali", 12934 "Africa/Maputo|Africa/Lubumbashi", 12935 "Africa/Maputo|Africa/Lusaka", 12936 "Africa/Nairobi|Africa/Addis_Ababa", 12937 "Africa/Nairobi|Africa/Asmara", 12938 "Africa/Nairobi|Africa/Asmera", 12939 "Africa/Nairobi|Africa/Dar_es_Salaam", 12940 "Africa/Nairobi|Africa/Djibouti", 12941 "Africa/Nairobi|Africa/Kampala", 12942 "Africa/Nairobi|Africa/Mogadishu", 12943 "Africa/Nairobi|Indian/Antananarivo", 12944 "Africa/Nairobi|Indian/Comoro", 12945 "Africa/Nairobi|Indian/Mayotte", 12946 "Africa/Tripoli|Libya", 12947 "America/Adak|America/Atka", 12948 "America/Adak|US/Aleutian", 12949 "America/Anchorage|US/Alaska", 12950 "America/Argentina/Buenos_Aires|America/Buenos_Aires", 12951 "America/Argentina/Catamarca|America/Argentina/ComodRivadavia", 12952 "America/Argentina/Catamarca|America/Catamarca", 12953 "America/Argentina/Cordoba|America/Cordoba", 12954 "America/Argentina/Cordoba|America/Rosario", 12955 "America/Argentina/Jujuy|America/Jujuy", 12956 "America/Argentina/Mendoza|America/Mendoza", 12957 "America/Cayenne|Etc/GMT+3", 12958 "America/Chicago|CST6CDT", 12959 "America/Chicago|US/Central", 12960 "America/Denver|America/Shiprock", 12961 "America/Denver|MST7MDT", 12962 "America/Denver|Navajo", 12963 "America/Denver|US/Mountain", 12964 "America/Detroit|US/Michigan",
12965 "America/Edmonton|Canada/Mountain", 12966 "America/Fort_Wayne|America/Indiana/Indianapolis", 12967 "America/Fort_Wayne|America/Indianapolis", 12968 "America/Fort_Wayne|US/East-Indiana", 12969 "America/Halifax|Canada/Atlantic", 12970 "America/Havana|Cuba", 12971 "America/Indiana/Knox|America/Knox_IN", 12972 "America/Indiana/Knox|US/Indiana-Starke", 12973 "America/Jamaica|Jamaica", 12974 "America/Kentucky/Louisville|America/Louisville", 12975 "America/La_Paz|Etc/GMT+4", 12976 "America/Los_Angeles|PST8PDT", 12977 "America/Los_Angeles|US/Pacific", 12978 "America/Los_Angeles|US/Pacific-New", 12979 "America/Manaus|Brazil/West", 12980 "America/Mazatlan|Mexico/BajaSur", 12981 "America/Mexico_City|Mexico/General", 12982 "America/New_York|EST5EDT", 12983 "America/New_York|US/Eastern", 12984 "America/Noronha|Brazil/DeNoronha", 12985 "America/Panama|America/Atikokan", 12986 "America/Panama|America/Cayman", 12987 "America/Panama|America/Coral_Harbour", 12988 "America/Panama|EST", 12989 "America/Phoenix|America/Creston", 12990 "America/Phoenix|MST", 12991 "America/Phoenix|US/Arizona", 12992 "America/Puerto_Rico|America/Anguilla", 12993 "America/Puerto_Rico|America/Antigua", 12994 "America/Puerto_Rico|America/Aruba", 12995 "America/Puerto_Rico|America/Blanc-Sablon", 12996 "America/Puerto_Rico|America/Curacao", 12997 "America/Puerto_Rico|America/Dominica", 12998 "America/Puerto_Rico|America/Grenada", 12999 "America/Puerto_Rico|America/Guadeloupe", 13000 "America/Puerto_Rico|America/Kralendijk", 13001 "America/Puerto_Rico|America/Lower_Princes", 13002 "America/Puerto_Rico|America/Marigot", 13003 "America/Puerto_Rico|America/Montserrat", 13004 "America/Puerto_Rico|America/Port_of_Spain", 13005 "America/Puerto_Rico|America/St_Barthelemy", 13006 "America/Puerto_Rico|America/St_Kitts", 13007 "America/Puerto_Rico|America/St_Lucia", 13008 "America/Puerto_Rico|America/St_Thomas", 13009 "America/Puerto_Rico|America/St_Vincent", 13010 "America/Puerto_Rico|America/Tortola", 13011 "America/Puerto_Rico|America/Virgin", 13012 "America/Regina|Canada/Saskatchewan", 13013 "America/Rio_Branco|America/Porto_Acre", 13014 "America/Rio_Branco|Brazil/Acre", 13015 "America/Santiago|Chile/Continental", 13016 "America/Sao_Paulo|Brazil/East",
13017 "America/St_Johns|Canada/Newfoundland", 13018 "America/Tijuana|America/Ensenada", 13019 "America/Tijuana|America/Santa_Isabel", 13020 "America/Tijuana|Mexico/BajaNorte", 13021 "America/Toronto|America/Montreal", 13022 "America/Toronto|America/Nassau", 13023 "America/Toronto|Canada/Eastern", 13024 "America/Vancouver|Canada/Pacific", 13025 "America/Whitehorse|Canada/Yukon", 13026 "America/Winnipeg|Canada/Central", 13027 "Asia/Ashgabat|Asia/Ashkhabad", 13028 "Asia/Bangkok|Asia/Phnom_Penh", 13029 "Asia/Bangkok|Asia/Vientiane", 13030 "Asia/Bangkok|Etc/GMT-7", 13031 "Asia/Bangkok|Indian/Christmas", 13032 "Asia/Brunei|Asia/Kuching", 13033 "Asia/Brunei|Etc/GMT-8", 13034 "Asia/Dhaka|Asia/Dacca", 13035 "Asia/Dubai|Asia/Muscat", 13036 "Asia/Dubai|Etc/GMT-4", 13037 "Asia/Dubai|Indian/Mahe", 13038 "Asia/Dubai|Indian/Reunion", 13039 "Asia/Ho_Chi_Minh|Asia/Saigon", 13040 "Asia/Hong_Kong|Hongkong", 13041 "Asia/Jerusalem|Asia/Tel_Aviv", 13042 "Asia/Jerusalem|Israel", 13043 "Asia/Kathmandu|Asia/Katmandu", 13044 "Asia/Kolkata|Asia/Calcutta", 13045 "Asia/Kuala_Lumpur|Asia/Singapore", 13046 "Asia/Kuala_Lumpur|Singapore", 13047 "Asia/Macau|Asia/Macao", 13048 "Asia/Makassar|Asia/Ujung_Pandang", 13049 "Asia/Nicosia|Europe/Nicosia", 13050 "Asia/Qatar|Asia/Bahrain", 13051 "Asia/Rangoon|Asia/Yangon", 13052 "Asia/Rangoon|Indian/Cocos", 13053 "Asia/Riyadh|Antarctica/Syowa", 13054 "Asia/Riyadh|Asia/Aden", 13055 "Asia/Riyadh|Asia/Kuwait", 13056 "Asia/Riyadh|Etc/GMT-3", 13057 "Asia/Seoul|ROK", 13058 "Asia/Shanghai|Asia/Chongqing", 13059 "Asia/Shanghai|Asia/Chungking", 13060 "Asia/Shanghai|Asia/Harbin", 13061 "Asia/Shanghai|PRC", 13062 "Asia/Taipei|ROC", 13063 "Asia/Tehran|Iran", 13064 "Asia/Thimphu|Asia/Thimbu", 13065 "Asia/Tokyo|Japan", 13066 "Asia/Ulaanbaatar|Asia/Ulan_Bator", 13067 "Asia/Urumqi|Antarctica/Vostok", 13068 "Asia/Urumqi|Asia/Kashgar",
13069 "Asia/Urumqi|Etc/GMT-6", 13070 "Atlantic/Faroe|Atlantic/Faeroe", 13071 "Atlantic/South_Georgia|Etc/GMT+2", 13072 "Australia/Adelaide|Australia/South", 13073 "Australia/Brisbane|Australia/Queensland", 13074 "Australia/Broken_Hill|Australia/Yancowinna", 13075 "Australia/Darwin|Australia/North", 13076 "Australia/Hobart|Australia/Tasmania", 13077 "Australia/Lord_Howe|Australia/LHI", 13078 "Australia/Melbourne|Australia/Victoria", 13079 "Australia/Perth|Australia/West", 13080 "Australia/Sydney|Australia/ACT", 13081 "Australia/Sydney|Australia/Canberra", 13082 "Australia/Sydney|Australia/NSW", 13083 "Etc/UTC|Etc/UCT", 13084 "Etc/UTC|Etc/Universal", 13085 "Etc/UTC|Etc/Zulu", 13086 "Etc/UTC|UCT", 13087 "Etc/UTC|UTC", 13088 "Etc/UTC|Universal", 13089 "Etc/UTC|Zulu", 13090 "Europe/Belgrade|Europe/Ljubljana", 13091 "Europe/Belgrade|Europe/Podgorica", 13092 "Europe/Belgrade|Europe/Sarajevo", 13093 "Europe/Belgrade|Europe/Skopje", 13094 "Europe/Belgrade|Europe/Zagreb", 13095 "Europe/Berlin|Arctic/Longyearbyen", 13096 "Europe/Berlin|Atlantic/Jan_Mayen", 13097 "Europe/Berlin|Europe/Copenhagen", 13098 "Europe/Berlin|Europe/Oslo", 13099 "Europe/Berlin|Europe/Stockholm", 13100 "Europe/Brussels|CET", 13101 "Europe/Brussels|Europe/Amsterdam", 13102 "Europe/Brussels|Europe/Luxembourg", 13103 "Europe/Chisinau|Europe/Tiraspol", 13104 "Europe/Dublin|Eire", 13105 "Europe/Helsinki|Europe/Mariehamn", 13106 "Europe/Istanbul|Asia/Istanbul", 13107 "Europe/Istanbul|Turkey", 13108 "Europe/Lisbon|Portugal", 13109 "Europe/London|Europe/Belfast", 13110 "Europe/London|Europe/Guernsey", 13111 "Europe/London|Europe/Isle_of_Man", 13112 "Europe/London|Europe/Jersey", 13113 "Europe/London|GB", 13114 "Europe/London|GB-Eire", 13115 "Europe/Moscow|W-SU", 13116 "Europe/Paris|Europe/Monaco", 13117 "Europe/Prague|Europe/Bratislava", 13118 "Europe/Rome|Europe/San_Marino", 13119 "Europe/Rome|Europe/Vatican", 13120 "Europe/Warsaw|Poland", 13121 "Europe/Zurich|Europe/Busingen", 13122 "Europe/Zurich|Europe/Vaduz", 13123 "Indian/Maldives|Etc/GMT-5", 13124 "Indian/Maldives|Indian/Kerguelen", 13125 "Pacific/Auckland|Antarctica/McMurdo", 13126 "Pacific/Auckland|Antarctica/South_Pole", 13127 "Pacific/Auckland|NZ", 13128 "Pacific/Chatham|NZ-CHAT", 13129 "Pacific/Easter|Chile/EasterIsland", 13130 "Pacific/Gambier|Etc/GMT+9", 13131 "Pacific/Guadalcanal|Etc/GMT-11", 13132 "Pacific/Guadalcanal|Pacific/Pohnpei", 13133 "Pacific/Guadalcanal|Pacific/Ponape", 13134 "Pacific/Guam|Pacific/Saipan", 13135 "Pacific/Honolulu|HST", 13136 "Pacific/Honolulu|Pacific/Johnston", 13137 "Pacific/Honolulu|US/Hawaii", 13138 "Pacific/Kwajalein|Kwajalein", 13139 "Pacific/Pago_Pago|Pacific/Midway", 13140 "Pacific/Pago_Pago|Pacific/Samoa", 13141 "Pacific/Pago_Pago|US/Samoa", 13142 "Pacific/Palau|Etc/GMT-9", 13143 "Pacific/Port_Moresby|Antarctica/DumontDUrville", 13144 "Pacific/Port_Moresby|Etc/GMT-10", 13145 "Pacific/Port_Moresby|Pacific/Chuuk", 13146 "Pacific/Port_Moresby|Pacific/Truk", 13147 "Pacific/Port_Moresby|Pacific/Yap", 13148 "Pacific/Tahiti|Etc/GMT+10", 13149 "Pacific/Tarawa|Etc/GMT-12", 13150 "Pacific/Tarawa|Pacific/Funafuti", 13151 "Pacific/Tarawa|Pacific/Majuro", 13152 "Pacific/Tarawa|Pacific/Wake", 13153 "Pacific/Tarawa|Pacific/Wallis" 13154 ] 13155 }); 13156 13157 13158 return moment; 13159})); 13160 13161; 13162////pf: javascript/radial-progress-gauge.js 13163 13164$.fn.radialProgress = function (options) { 13165 13166 $(this).each(function () { 13167 let { radius, color, backgroundColor, maxValue, minValue, value, strokeWidth } = $.extend({ 13168 radius: 21, 13169 color: '#090', 13170 backgroundColor: '#BBB', 13171 maxValue: 100, 13172 minValue: 0, 13173 value: 0, 13174 strokeWidth: 5 13175 }, options); 13176 13177 const fraction = Math.max(0, value / (maxValue - minValue)); 13178 const normalizedFraction = Math.min(1, fraction); 13179 13180 radius = Number(radius); 13181 strokeWidth = Number(strokeWidth);
13182 13183 const svgRadius = radius - strokeWidth / 2; 13184 13185 const getArc = ({ color, fraction, fractionOffset }) => { 13186 return `<path class="pie-gauge-arc" 13187 d="${$.describeArc(radius, radius, svgRadius, fractionOffset * 360, (fractionOffset + fraction) * 360)}" 13188 style="stroke:${color}; stroke-width: ${strokeWidth.toFixed(4)}px; fill: transparent;" > 13189 </path>` 13190 }; 13191 13192 const arcs = [ 13193 getArc({ 13194 color: color, 13195 fraction: normalizedFraction, 13196 fractionOffset: 0 13197 }), 13198 getArc({ 13199 color: backgroundColor, 13200 fraction: Math.max(0, 1 - normalizedFraction), 13201 fractionOffset: normalizedFraction 13202 }) 13203 ]; 13204 13205 const svg = `<div class="radial-progress-gauge" style="font-size: 1rem; width: 100%; height: ${(radius * 2).toFixed(4)}px;"> 13206 <svg viewPort="0 0 100 100" style="width: 100%; height: 100%;" version="1.1" xmlns="http://www.w3.org/2000/svg" > 13207 ${arcs.join('\n')} 13208 <text class='radial-progress-gauge-label' x="${radius}" y="50%">${(fraction * 100).toFixed(0)}%</text> 13209 </svg> 13210 </div>`; 13211 13212 $(this).append(svg); 13213 }); 13214 13215 return this; 13216}; 13217 13218 13219$(function () { 13220 $('[radial-progress]').each(function () { 13221 $(this).addClass('created'); 13222 $(this).radialProgress({ 13223 radius: $(this).attr('radius'), 13224 color: $(this).attr('color'), 13225 backgroundColor: $(this).attr('background-color'), 13226 maxValue: $(this).attr('max-value'), 13227 minValue: $(this).attr('min-value'), 13228 value: $(this).attr('value'), 13229 strokeWidth: $(this).attr('stroke-width') 13230 }); 13231 }); 13232}); 13233 13234 13235 13236; 13237////pf: javascript/pie-gauge.js 13238 13239const truncateNumber = (num) => { 13240 return num.toString().substring(0, Math.floor(num).toString().length + 5) 13241}; 13242 13243// see https://stackoverflow.com/questions/5736398/how-to-calculate-the-svg-path-for-an-arc-of-a-circle 13244const polarToCartesian = (centerX, centerY, radius, angleInDegrees) => { 13245 const angleInRadians = (angleInDegrees - 90) * Math.PI / 180.0; 13246 13247 return { 13248 x: centerX + (radius * Math.cos(angleInRadians)), 13249 y: centerY + (radius * Math.sin(angleInRadians)) 13250 }; 13251};
13252 13253$.describeArc = (x, y, radius, startAngle, endAngle) => { 13254 const start = polarToCartesian(x, y, radius, endAngle); 13255 const end = polarToCartesian(x, y, radius, startAngle); 13256 const largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1"; 13257 13258 const d = [ 13259 "M", truncateNumber(start.x), truncateNumber(start.y), 13260 "A", radius, radius, 0, largeArcFlag, 0, truncateNumber(end.x), truncateNumber(end.y) 13261 ].join(" "); 13262 13263 return d; 13264}; 13265 13266 13267$.fn.pieGauge = function (options) { 13268 const colors = [ 13269 '#f94144', 13270 '#577590', 13271 '#f3722c', 13272 '#871b4a', 13273 '#43aa8b', 13274 '#f9c74f', 13275 '#A7A5C6', 13276 '#8797b2', 13277 '#6d8a96', 13278 '#90be6d', 13279 '#66ced6', 13280 '#053c5e', 13281 '#a31621', 13282 '#b5ef8a' 13283 ]; 13284 13285 $(this).each(function () { 13286 let { radius, strokeWidth, segments, innerValue, innerLabel, keyType } = $.extend({ 13287 radius: 18, 13288 strokeWidth: 6, 13289 innerValue: '', 13290 innerLabel: '', 13291 segments: [], 13292 keyType: 'bottom' 13293 }, options); 13294 13295 radius = Number(radius); 13296 strokeWidth = Number(strokeWidth); 13297 13298 const svgRadius = radius - strokeWidth / 2; 13299 13300 const getArc = ({ color, fraction, fractionOffset }) => { 13301 return `<path class="pie-gauge-arc" 13302 d="${$.describeArc(radius, radius, svgRadius, fractionOffset * 360, (fractionOffset + fraction) * 360)}" 13303 style="stroke:${color}; stroke-width: ${strokeWidth.toFixed(4)}px; fill: transparent;" > 13304 </path>` 13305 }; 13306 13307 const arcs = []; 13308 const svgKey = []; 13309 const htmlKey = []; 13310 let offset = 0; 13311 const total = segments.reduce((acc, s) => acc + s.Value || 0, 0); 13312 const labelOffset = radius * 2 + strokeWidth / 2 + 20; 13313 13314 if (total === 0) 13315 return; 13316 13317 segments 13318 .forEach((s, index) => { 13319 const { Value, Color } = s; 13320 if (Value === 0) 13321 return; 13322 13323 const fraction = Value / total; 13324 13325 arcs.push( 13326 getArc({ 13327 color: Color || colors[index % colors.length], 13328 fraction: fraction, 13329 fractionOffset: offset 13330 }) 13331 ); 13332 13333 arcs.push( 13334 getArc({
13335 color: '#FFFFFF', 13336 fraction: 0.005, 13337 fractionOffset: offset + fraction - 0.005 13338 }) 13339 ); 13340 13341 offset += fraction; 13342 }); 13343 13344 if (keyType === 'right') { 13345 segments 13346 .forEach((s, index) => { 13347 svgKey.push(` 13348 <rect width="14" height="14" x="${labelOffset}" y="${index * 18 + 4}" style="fill: ${(s.Color || colors[index % colors.length])};" /> 13349 <text x="${labelOffset + 20}" y="${index * 18 + 15}">${s.Name}</text> 13350 <text x="100%" y="${index * 18 + 15}" style='text-anchor: end;'>${s.FormattedValue ?? ""}</text> 13351 `); 13352 }); 13353 } else if (keyType === 'bottom') { 13354 segments 13355 .forEach((s, index) => { 13356 htmlKey.push(`<div class='html-key-child'> 13357 <div class='label'>${s.Name}</div> 13358 <div class='value' style='color: ${(s.Color || colors[index % colors.length])};'>${s.FormattedValue ?? ""}</div> 13359 </div>`); 13360 }); 13361 } 13362 13363 const getYPlacement = () => { 13364 const hasMultipleLines = isJson(innerLabel); 13365 13366 const PADDING_BETWEEN = 10; 13367 const LABEL_LINE_HEIGHT = 21; 13368 const PERCENTAGE_OF_DIAMETER = 0.55; 13369 13370 const valueFromPercent = PERCENTAGE_OF_DIAMETER * (radius * 2); 13371 const withPaddingOffset = valueFromPercent - (PADDING_BETWEEN / 2); 13372 13373 const innerValueY = hasMultipleLines ? withPaddingOffset - (LABEL_LINE_HEIGHT / 2) : withPaddingOffset; 13374 const innerLabelY = innerValueY + PADDING_BETWEEN + LABEL_LINE_HEIGHT; 13375 13376 return { innerValueY, innerLabelY }; 13377 } 13378 13379 let innerLabelPresentation; 13380 // if string is json, needs line breaks 13381 13382 if (isJson(innerLabel)) { 13383 innerLabelPresentation = JSON.parse(innerLabel).map((label, i) => 13384 `<text x='${radius}' y='${getYPlacement().innerLabelY + (i * 21)}' class='inner-label'>${label}</text>` 13385 ).join('\n') 13386 } else { 13387 innerLabelPresentation = `<text x='${radius}' y='${getYPlacement().innerLabelY}' class='inner-label'>${innerLabel}</text>` 13388 } 13389 13390 const svg = `<div class="pie-gauge" style="font-size: 1rem; width: 100%; height: ${(radius * 2).toFixed(4)}px;"> 13391 <svg viewPort="0 0 100 100" style="width: ${(keyType === 'bottom' ? (radius * 2).toFixed(4) + 'px' : '100%')}; height: 100%;" version="1.1" xmlns="http://www.w3.org/2000/svg" > 13392 ${arcs.join('\n')} 13393 ${svgKey.join('\n')} 13394 <text x='${radius}' y='${getYPlacement().innerValueY}' class='inner-value'>${innerValue}</text> 13395 ${innerLabelPresentation} 13396 </svg> 13397 <div class='html-key'>${htmlKey.join('\n')}</div> 13398 </div>`; 13399 13400 $(this).append(svg); 13401 }); 13402 13403 return this; 13404}; 13405 13406$(function () { 13407 $('[pie-gauge]').each(function () { 13408 let segments = []; 13409 13410 try { 13411 segments = JSON.parse($(this).attr('segments')); 13412 } 13413 catch (err) { 13414 console.warn('unable to make pie gauge', err); 13415 return; 13416 } 13417 13418 $(this).pieGauge({ 13419 radius: $(this).attr('radius'), 13420 strokeWidth: $(this).attr('stroke-width'), 13421 innerValue: $(this).attr('inner-value'), 13422 innerLabel: $(this).attr('inner-label'), 13423 segments 13424 }); 13425 }); 13426}); 13427 13428const isJson = (str) => { 13429 str = typeof str !== "string" 13430 ? JSON.stringify(str) 13431 : str; 13432 13433 try { 13434 str = JSON.parse(str); 13435 } catch (e) { 13436 return false; 13437 } 13438 13439 if (typeof str === "object" && str !== null) { 13440 return true; 13441 } 13442 13443 return false; 13444} 13445 13446; 13447////pf: javascript/mysmp.js 13448 13449if (typeof (SMP) === 'undefined') { 13450 var SMP = {}; 13451} 13452 13453 13454// TODO: Move to a constants file once modules are available for JS files. (Webpack build overhaul) 13455window.PLATFORM_FEE_MODAL_TITLE = 'PlayerFirst Platform Fee Overview'; 13456window.PLATFORM_FEE_MODAL_CONTENT = `The PlayerFirst⢠Platform Fee (the "PF Platform Fee") helps cover the costs of managing the PlayerFirst platform used to register participants in events and programs and is shared between various parties involved in supporting the registration transactions and/or organizing our programs, and may include a profit to those parties.<br><br> 13457The PF Platform Fee is applied to the full sticker price or "face price" of a registration, entrance, subscription, product or gate purchase, not including a) any pro-rates, discounts, or scholarships applied, b) applicable sales tax, c) shipping fees, d) installment fees, or d) registration insurance. A discount to the PF Platform Fee may be available when selecting certain payment methods.`; 13458 13459//for forcing postback 13460//call like this: RealPostBack('<UniqueID of posting control>', ''); return false; 13461function RealPostBack(eventTarget, eventArgument) { 13462 setTimeout(function () { __doPostBack(eventTarget, eventArgument) },0); 13463} 13464 13465/* fixed position for left nav */ 13466function findPos(obj) { 13467 var curleft = curtop = 0; 13468 if (obj.offsetParent) { 13469 do { 13470 curleft += obj.offsetLeft; 13471 curtop += obj.offsetTop; 13472 } while (obj = obj.offsetParent); 13473 13474 return [curleft, curtop]; 13475 } 13476} 13477 13478/* expandable text boxes */ 13479$(document).ready(function () { 13480 if ($.growfield) { 13481 $('textarea.autogrow').growfield({ animate: false, step: 10 }); 13482 } 13483 13484 SMP.initTextAreaAutoHeight(); 13485}); 13486 13487function AttachAutogrow(obj) { 13488 if ($.growfield) { 13489 $(obj).growfield({ animate: false, step: 10 }); 13490 } 13491} 13492 13493SMP.attachTextAreaAutoHeight = function (element) { 13494 const $txt = $(element); 13495 const txt = $txt[0]; 13496 if (!txt) { 13497 return; 13498 } 13499 13500 if ($txt.data('autoHeightAttached')) { 13501 $txt.trigger('input'); 13502 return; 13503 } 13504 13505 $txt.data('autoHeightAttached', true); 13506
13507 const $hiddenDiv = $('<div>').css({ 13508 position: 'absolute', 13509 top: -9999, 13510 left: -9999, 13511 visibility: 'hidden', 13512 whiteSpace: 'pre-wrap', 13513 wordWrap: 'break-word', 13514 overflowWrap: 'break-word', 13515 }); 13516 $('body').append($hiddenDiv); 13517 13518 const minHeight = parseInt($txt.css('min-height'), 10) || 16; 13519 13520 const getVerticalChrome = function () { 13521 const offset = txt.offsetHeight; 13522 const client = txt.clientHeight; 13523 if (offset > 0 && client > 0) { 13524 return offset - client; 13525 } 13526 13527 const style = window.getComputedStyle(txt); 13528 return parseFloat(style.paddingTop) + parseFloat(style.paddingBottom) 13529 + parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth); 13530 }; 13531 13532 const resize = function () { 13533 const style = window.getComputedStyle(txt); 13534 $hiddenDiv.css({ 13535 width: txt.clientWidth + 'px', 13536 fontFamily: style.fontFamily, 13537 fontSize: style.fontSize, 13538 fontWeight: style.fontWeight, 13539 lineHeight: style.lineHeight, 13540 letterSpacing: style.letterSpacing, 13541 }); 13542 $hiddenDiv.text($txt.val()); 13543 13544 const contentHeight = $hiddenDiv[0].offsetHeight; 13545 const padding = getVerticalChrome(); 13546 $txt.css('height', Math.max(minHeight, contentHeight + padding)); 13547 }; 13548 13549 $txt.on('keyup input', resize); 13550 resize(); 13551}; 13552 13553SMP.initTextAreaAutoHeight = function (root) { 13554 $(root || document).find('textarea[data-auto-height]').each(function () { 13555 SMP.attachTextAreaAutoHeight(this); 13556 }); 13557}; 13558 13559/* Error Relay */ 13560function relayError(message, url, line, handlerUrl, notify) { 13561 // message == text-based error description 13562 // url == url which exhibited the script error 13563 // line == the line number being executed when the error occurred 13564 13565 if ( 13566 line == 0 // line shows as zero when browser refuses to pass information about script due to security restrictions 13567 || url == "" 13568 || typeof(url) === "undefined" 13569 && ( 13570 typeof (message) === "undefined" 13571 || !message.indexOf //not a string, wtf 13572 || message == "Script error." //crossed domain boundary, ie iframe/plugin error, not actionable 13573 || message.indexOf("to call method UnnamedClass.toString on <>") != -1 //worthless error 13574 || message.indexOf("chrome://") != -1 //worthless error 13575 )) 13576 { 13577 return(true); 13578 } 13579 13580 $.post(handlerUrl, "{'line':'" + line + "', 'url':'" + url + "', 'message':'" + message + "', 'notify':'" + !!notify + "'}"); 13581 return true; 13582} 13583 13584 13585//maximum checkboxes selected per region 13586$(function () { 13587 $('[MaxSelections]').each(function () { 13588 var max = parseInt($(this).attr('MaxSelections'), 10); 13589 var context = $(this); 13590 $(this).find('[type=checkbox]').change( 13591 function () { 13592 if ($(this).prop('checked')) { 13593 MaxSelectionsChanged.call(context, this); 13594 $(this).prop('checked', true); 13595 } 13596 } 13597 ); 13598 }); 13599}); 13600 13601function MaxSelectionsChanged (from) { 13602 this.find('[type=checkbox]').each(function () { 13603 if ($(this).prop('checked') && from != this) { 13604 $(this).prop('checked', false).change(); 13605 } 13606 }); 13607} 13608 13609function ExpandoBoxesFindBottom(source) { 13610 var bottom = source.find('+ .BoxBottom'); 13611 if (bottom.length != 1) { 13612 bottom = source.parent().find('+ .BoxBottom'); 13613 } 13614 return (bottom); 13615} 13616 13617function ExpandoBoxes(jqObj) { 13618 $(jqObj).find('.BoxTop').each(function () { 13619 var bottom = ExpandoBoxesFindBottom($(this)); 13620 if (bottom.length == 1) { 13621 $(this).css('cursor', 'pointer') 13622 .css('font-weight', 'bold') 13623 .append(' (Click for Info)') 13624 .prepend('<div class=\"Expandable\"></div>'); 13625 } 13626 bottom.css('overflow', 'hidden').css('padding', '0').css('visibility', 'hidden').height('1px').addClass('hidden'); 13627 $(this).click(function () { 13628 var bottom = ExpandoBoxesFindBottom($(this)); 13629 if (bottom.hasClass('hidden')) { 13630 bottom.css('padding', '10px').height('auto').css('visibility', 'visible'); 13631 } 13632 else { 13633 bottom.css('padding', '0').height('1px').css('visibility', 'hidden'); 13634 } 13635 bottom.toggleClass('hidden'); 13636 }); 13637 });
13638} 13639 13640$(function () { ExpandoBoxes($('.ExpandoBoxText')); }); 13641 13642function StripHtml(html) { 13643 return(html.replace(/(<([^>]+)>)/ig, "")); 13644} 13645 13646var IdleManager = { 13647 IdleWarningPanelID: "IdleWarningPanel", 13648 CancelLogOutButtonID: "StayLoggedInButton", 13649 Interval: Infinity, 13650 MaxMinutes: Infinity, 13651 LogoutCountdown: 60, 13652 RemainingCountdown: 60, 13653 CountdownInterval: null, 13654 Register: function (interval, maxMinutes) { 13655 this.Interval = interval; 13656 this.MaxMinutes = maxMinutes; 13657 this.ActionOccurred = false; 13658 13659 setTimeout(this.CheckTimeout, this.Interval); 13660 13661 $('#' + this.CancelLogOutButtonID).click(function () { 13662 IdleManager.CancelCountdownLogout(); 13663 $.fn.modalElement.close(); 13664 IdleManager.WakeUp(); 13665 return (false); 13666 }); 13667 13668 window.addEventListener('mousedown', function () { IdleManager.ActionOccurred = true; }); 13669 window.addEventListener('keydown', function () { IdleManager.ActionOccurred = true; }); 13670 }, 13671 CheckTimeout: function () { 13672 if (IdleManager.ActionOccurred) { 13673 IdleManager.ActionOccurred = false; 13674 IdleManager.WakeUp(); 13675 } else { 13676 IdleManager.CheckTimeoutHandler(IdleManager.GetIdleMinutes()); 13677 } 13678 }, 13679 CheckTimeoutHandler: function (minutes) { 13680 if (minutes > IdleManager.MaxMinutes - 2) { 13681 if (minutes > IdleManager.MaxMinutes) { 13682 LogOut(); 13683 } 13684 else { 13685 IdleManager.RemainingCountdown = IdleManager.LogoutCountdown; 13686 var html = '<div id="IdleWarningPanel" class="Warning" style="font-size:18px; padding:40px; margin: 0; display: block;">' 13687 + 'You are about to be logged out due to inactivity' 13688 + '<div id="IdleWarningPanelCountdown" style="padding:10px 0 10px 0;">' + IdleManager.CountdownMessage() + '</div>' 13689 + '<button type="button" id="StayLoggedInButton" class="ForwardButton" onclick="IdleManager.CancelCountdownLogout();">Stay Logged In</button>' 13690 + '</div>'; 13691 13692 $.fn.modalElement.open({ content: html }); 13693 IdleManager.CountdownLogout(); 13694 } 13695 } 13696 else { 13697 setTimeout(IdleManager.CheckTimeout, IdleManager.Interval); 13698 } 13699 }, 13700 CountdownLogout: function () { 13701 IdleManager.RemainingCountdown = 120; 13702 IdleManager.CountdownInterval = setInterval(IdleManager.Countdown, 1000); 13703 }, 13704 Countdown: function () { 13705 IdleManager.RemainingCountdown--; 13706 if (IdleManager.RemainingCountdown > 0) { 13707 $('#IdleWarningPanelCountdown').html(IdleManager.CountdownMessage()); 13708 } 13709 else { //last chance, in case updated from another window 13710 if (IdleManager.GetIdleMinutes() > IdleManager.MaxMinutes) { 13711 LogOut(); 13712 } else { 13713 IdleManager.CancelCountdownLogout(); 13714 } 13715 } 13716 }, 13717 CountdownMessage: function () { 13718 return ('Click Within ' + IdleManager.RemainingCountdown + ' Seconds'); 13719 }, 13720 CancelCountdownLogout: function () { 13721 IdleManager.WakeUp(); 13722 $.fn.modalElement.close(); 13723 }, 13724 WakeUp: function () { 13725 fetch("/util/wakeup.ashx"); 13726 13727 try { 13728 clearInterval(IdleManager.CountdownInterval); 13729 } catch (err) { } 13730 13731 setTimeout(IdleManager.CheckTimeout, IdleManager.Interval); 13732 }, 13733 GetIdleMinutes: function () { 13734 var cookie = document.cookie.match(/UtcLastActive=([^;]*)/); 13735 if (cookie) { 13736 return moment.utc().diff(moment.utc(cookie[1]), 'm'); 13737 } 13738 } 13739} 13740 13741function LogOut() { 13742 fetch("/util/logout.ashx") 13743 .then(() => window.location.href = window.location.href); // refresh 13744} 13745 13746 13747//Animate to any anchors instead of boring jump 13748$(function () { 13749 $('a[href^="#"]').each(function () { 13750 var target = $(this).attr('href').substr(1); 13751 13752 $(this).click(function () {
13753 animateToAnchor(target); 13754 }); 13755 }); 13756}); 13757function animateToAnchor( target ) 13758{ 13759 if (!target || target.match(/\//g)) { 13760 // forward slashes in target will be an invalid ID 13761 return; 13762 } 13763 13764 let jqTarget = $(`#${target}, a[name="${target}"]`); 13765 let offset = 0; 13766 13767 let inOverflowY = jqTarget.parents( "div, td, table" ).filter( function () 13768 { 13769 if ( $( this ).attr( "id" ) === "MainContent" ) 13770 { 13771 offset = -140; 13772 return false; 13773 } 13774 return $( this ).css( 'overflow' ) != 'visible' || $( this ).css( 'overflow-y' ) != 'visible'; 13775 }); 13776 13777 if ( inOverflowY.length ) 13778 { 13779 jqTarget = inOverflowY.first(); 13780 } 13781 13782 if ( !jqTarget.length ) 13783 { 13784 jqTarget = $( '#' + target ); 13785 } 13786 13787 animateToJqObject( jqTarget, offset ); 13788} 13789function animateToJqObject(jqTarget, offset) { 13790 if (jqTarget.length > 0) { 13791 if (jqTarget.data("anchor-offset")) { 13792 offset = jqTarget.data("anchor-offset"); 13793 } 13794 13795 var targetTop = jqTarget.offset().top; 13796 $('html,body').animate({ scrollTop: targetTop + (offset ? offset : 0) }, 400); 13797 } 13798} 13799 13800 13801var countdown = function () 13802{ 13803 var time_left = 0; 13804 var output_element_id = 'javascript_countdown_time'; 13805 var keep_counting = 1; 13806 var timeoutId = 0; 13807 13808 var countdown = function () 13809 { 13810 if( time_left < 2 ) 13811 { 13812 keep_counting = 0; 13813 } 13814 time_left = time_left - 1; 13815 }; 13816 13817 var add_leading_zero = function ( n ) 13818 { 13819 if( n.toString().length < 2 ) 13820 { 13821 return '0' + n; 13822 } else 13823 { 13824 return n; 13825 } 13826 }; 13827 13828 var format_output = function () 13829 { 13830 var 13831 days = add_leading_zero( Math.max( 0, Math.floor( time_left / ( 3600 * 24 ) ) ) ), 13832 hours = add_leading_zero( Math.max( 0, Math.floor( time_left / 3600 ) % 24 ) ), 13833 minutes = add_leading_zero( Math.max( 0, Math.floor( time_left / 60 ) % 60 ) ), 13834 seconds = add_leading_zero( Math.max( 0, time_left % 60 ) ); 13835 13836 return ( "<span class='CountdownDays'>" + days + "<label>Days</label></span><span class='CountdownHours'>" + hours + "<label>Hours</label></span><span class='CountdownMinutes'>" + minutes + "<label>Mins</label></span><span class='CountdownSeconds'>" + seconds + "<label>Secs</label></span>" ); 13837 }; 13838 13839 var show_time_left = function () 13840 { 13841 document.getElementById( output_element_id ).innerHTML = format_output(); //time_left; 13842 }; 13843 13844 return { 13845 count: function () 13846 { 13847 countdown(); 13848 show_time_left(); 13849 }, 13850 timer: function () 13851 { 13852 this.count(); 13853 13854 if( keep_counting ) 13855 { 13856 var context = this; 13857 timeoutId = setTimeout( function () { context.timer() }, 1000 ); 13858 } else 13859 { 13860 //this.timer(); 13861 } 13862 }, 13863 setTimeLeft: function ( t ) 13864 { 13865 time_left = t; 13866 if( keep_counting == 0 ) 13867 { 13868 this.timer(); 13869 } 13870 }, 13871 init: function ( seconds, element_id ) 13872 { 13873 clearTimeout( timeoutId ); 13874 time_left = seconds; 13875 output_element_id = element_id; 13876 this.timer(); 13877 } 13878 }; 13879}(); 13880 13881var hasLocalStorage = ( function () 13882{ 13883 try 13884 { 13885 localStorage.setItem( "a", "a" ); //required 13886 localStorage.removeItem( "a" ); //required 13887 for( var i in localStorage ) { } //fails with firefox less than 4.0 13888 return true; 13889 } catch( e ) 13890 { 13891 return false; 13892 } 13893}() ); 13894 13895var RichEditorManager = { 13896 getUrl: function () { 13897 try { 13898 return (window.location.href.split('//')[1]); 13899 } 13900 catch (ex) { 13901 return ("url-permission-denied"); 13902 } 13903 }, 13904 getKey: function (jq) { 13905 var id = jq.attr('id'); 13906 return (unescape(this.getUrl()) + '-' + id); 13907 }, 13908 getKeyExpires: function (jq) { 13909 return (this.getKey(jq) + '-exp'); 13910 }, 13911 isKeyExpired: function (jq) { 13912 var exp = localStorage[this.getKeyExpires()]; 13913 return (new DateTime(exp)); 13914 }, 13915 getMatchingHtmlBody: function (jq) { 13916 var next = jq.next(); 13917 if (!next.is('iframe')) 13918 next = next.find('iframe'); 13919 return (next.contents().find('html body')); 13920 }, 13921 saveRichEditor: function () 13922 { 13923 try{ 13924 var me = this; 13925 $( 'textarea' ).each( function () 13926 { 13927 var html = me.getMatchingHtmlBody( $( this ) ).html(); 13928 localStorage[me.getKey( $( this ) )] = html; 13929 localStorage[me.getKeyExpires( $( this ) )] = new Date().setHours( new Date().getHours() + 2 ); 13930 } ); 13931 } 13932 catch( ex ) 13933 { 13934 localStorage.clear(); // lazy catch for "Persistent storage maximum size reached" 13935 } 13936 }, 13937 clearExpiredItems: function(){ 13938 var suffix = '-exp'; 13939 var max = 0; 13940 13941 for (var si in localStorage) { 13942 if (!si) { 13943 continue; 13944 } 13945 13946 if (si.indexOf(suffix, si.length - suffix.length) !== -1) { //endswith 13947 var exp = new Date(); 13948 exp.setTime(localStorage[si]); 13949 if (exp < new Date()) { 13950 localStorage[si] = null; 13951 localStorage[si.substring(0, si.length - 4)] = null; 13952 try{ 13953 localStorage.removeItem(si); 13954 localStorage.removeItem(si.substring(0, si.length - 4));
13955 } 13956 catch(x){} 13957 } 13958 } 13959 else if (localStorage[si] == "null" || localStorage[si] == "") { 13960 try { 13961 localStorage.removeItem(si); 13962 } 13963 catch (x) { } 13964 } 13965 max++; 13966 if (max > 20) { 13967 return; 13968 } 13969 } 13970 }, 13971 initializeRichTextEditor: function () { 13972 if (!hasLocalStorage) { 13973 return; 13974 } 13975 RichEditorManager.clearExpiredItems(); 13976 var me = this; 13977 if (this.isClearOnLoad()) { 13978 this.clear(); 13979 } 13980 else { 13981 $('textarea').each(function () { 13982 var matchingBody = me.getMatchingHtmlBody($(this)); 13983 if (matchingBody.html() && matchingBody.html().length < 50) { 13984 var exp = new Date(); 13985 var saved = localStorage[me.getKey($(this))]; 13986 exp.setTime(localStorage[me.getKeyExpires($(this))]); 13987 if (exp > new Date() && saved && saved.length > 50) { 13988 matchingBody.html(saved); 13989 } 13990 } 13991 }); 13992 } 13993 setInterval(function () { RichEditorManager.saveRichEditor(); }, 10000); 13994 13995 $('.ForwardButton, .DeleteButton').click(function () { me.setClearOnLoad(); }); 13996 }, 13997 clear: function () { 13998 var me = this; 13999 $('textarea').each(function () { 14000 localStorage[me.getKey($(this))] = ""; 14001 try { 14002 localStorage.removeItem(me.getKey($(this))); 14003 } 14004 catch (x) { } 14005 }); 14006 localStorage['clearOnLoad'] = ""; 14007 }, 14008 setClearOnLoad: function () { 14009 localStorage['clearOnLoad'] = this.getUrl(); 14010 }, 14011 isClearOnLoad: function () { 14012 return (localStorage['clearOnLoad'] == this.getUrl()); 14013 } 14014}; 14015 14016$(function () { 14017 setTimeout(function () { RichEditorManager.initializeRichTextEditor(); }, 5000); 14018}); 14019 14020function endsWith(str, suffix) { 14021 return str.indexOf(suffix, str.length - suffix.length) !== -1; 14022} 14023 14024$(function () { 14025 var hadFocus = null; 14026 var hadValue = null; 14027 $('input, select, textarea') 14028 .on('focus', function () { 14029 hadFocus = this; 14030 hadValue = $(this).val(); 14031 $(this).addClass('focused'); 14032 }) 14033 .on('blur', function () { 14034 if (this == hadFocus && hadValue != $(this).val()) { 14035 $(this).change(); //may be a bug with firefox 14036 } 14037 hadFocus = null; 14038 hadValue = null; 14039 $(this).removeClass('focused'); 14040 }) 14041 14042 $('.as-selections').click(function () { $(this).parent().addClass('focused'); }); 14043 $(document) 14044 .on('mousedown', function () { $('.as-selections').each(function () { $(this).parent().removeClass('focused'); }); }); 14045}); 14046 14047 14048var currentFixedHeader; 14049var currentGhost; 14050var ghostRealTable = null; 14051var followHeader = function () { 14052 $.fn.reverse = [].reverse; 14053 14054 var createGhostHeader = function (header, topOffset) { 14055 if (!header) 14056 return; 14057 14058 var containerWidth = Math.min($(ghostRealTable).outerWidth(false), $(ghostRealTable).parent().outerWidth(false), $(ghostRealTable).parent().parent().outerWidth(false)); 14059 14060 // Don't recreate if it is the same as the current one 14061 if (header == currentFixedHeader && currentGhost) { 14062 $(header).find('th:visible').each(function () { //reset widths of cells 14063 var matchingElement = $(currentGhost.find('th').eq($(this).index())); 14064 $(matchingElement).width($(this).width()); 14065 }); 14066 currentGhost.css({ 14067 'top': -topOffset + "px", 14068 'width': containerWidth + 'px' 14069 }).fadeTo(500, 1); 14070 return currentGhost; 14071 } 14072 14073 ghostRealTable = $(header).parents('table'); 14074 14075 if (currentGhost) 14076 $(currentGhost).remove(); 14077 14078 $(ghostRealTable).add($(ghostRealTable).parent()).add($(ghostRealTable).parent().parent()).scrollLeft(0); 14079 14080 var headerPosition = $(header).offset(); 14081 var tablePosition = $(ghostRealTable).offset(); 14082
14083 var container = $('<div></div>'); 14084 var containerTable = $('<table></table>'); 14085 container.append(containerTable); 14086 14087 // Copy attributes from old table (may not be what you want) 14088 if (ghostRealTable[0]) { 14089 for (var i = 0; i < ghostRealTable[0].attributes.length; i++) { 14090 var attr = ghostRealTable[0].attributes[i]; 14091 containerTable.attr(attr.name, attr.value); 14092 } 14093 } 14094 14095 // Set up position of fixed row 14096 container.css({ 14097 position: 'fixed', 14098 top: -topOffset, 14099 left: tablePosition.left, 14100 width: containerWidth, 14101 maxWidth: $(document).width(), 14102 display: 'block', 14103 whiteSpace: 'nowrap', 14104 overflow: 'hidden', 14105 backgroundColor: '#EEE' 14106 }); 14107 14108 containerTable.css({ 14109 position: 'relative', 14110 top: 0, 14111 left: 0 14112 }); 14113 14114 // Create a deep copy of our actual header and put it in our container 14115 var rows = $(header).find('tr').filter(function () { 14116 return (!$(this).hasClass('rgFilterRow')); 14117 }); 14118 if ($(header).hasClass('thead')) { 14119 rows = rows.add($(header)); 14120 } 14121 14122 var newHeader = $(header.cloneNode(false)).append(rows.clone()); 14123 14124 var newThs = $(newHeader).find('th'); 14125 14126 $(header).find('th:visible').each(function () { 14127 var matchingElement = $(newThs.eq($(this).index())); 14128 $(matchingElement).width($(this).width()).css({ 14129 'white-space': 'nowrap', 14130 'overflow': 'hidden', 14131 'display': 'inline-block' 14132 }); 14133 }); 14134 14135 newHeader.appendTo(containerTable); 14136 14137 currentGhost = container; 14138 currentFixedHeader = header; 14139 currentGhost.css('opacity', '0'); 14140 currentGhost.addClass('StickyGhost'); 14141 14142 // Add this fixed row to the same parent as the table 14143 $(ghostRealTable).parent().append(currentGhost); 14144 $(currentGhost).find('th').height($(currentGhost).height()); 14145 $(currentGhost).fadeTo(500, 1); 14146 14147 $(ghostRealTable).add($(ghostRealTable).parent()).add($(ghostRealTable).parent().parent()) 14148 .off("scroll") 14149 .on("scroll", function () { 14150 containerTable.css('left', '-' + $(this).scrollLeft() + 'px'); 14151 }); 14152 14153 return currentGhost; 14154 }; 14155 14156 14157 var currentScrollTop = $(document).scrollTop(); 14158 14159 var activeHeader = null; 14160 var table = $('table.StickyHeaders, .StickyHeaders table').filter(':visible'); 14161 if (!table.length) { 14162 return; 14163 } 14164 14165 var topOffset = 0; 14166 14167 var lastCheckedHeader = null; 14168 // We do these in reverse as we want the last good header 14169 var headers = table.find('thead,.thead').reverse().each(function () { 14170 if (!$(this).parents('.StickyGhost').length) { 14171 var position = $(this).offset(); 14172 if (position.top <= currentScrollTop && (!ghostRealTable || currentScrollTop < ghostRealTable.height() + ghostRealTable.offset().top - 10)) { 14173 activeHeader = this; 14174 return false; 14175 } 14176 lastCheckedHeader = this; 14177 } 14178 }); 14179 14180 if (lastCheckedHeader && activeHeader) { 14181 var offset = $(lastCheckedHeader).offset(); 14182 if (offset.top - currentScrollTop < $(activeHeader).height()) 14183 topOffset = $(activeHeader).height() - (offset.top - currentScrollTop) + 1; 14184 } 14185 14186 // No row is needed, get rid of one if there is one 14187 if (activeHeader == null && currentGhost) { 14188 currentGhost.css('display','none'); 14189 } 14190 else { 14191 createGhostHeader(activeHeader, topOffset); 14192 } 14193}; 14194 14195$(document).on('scroll', followHeader); 14196 14197 14198var followHeaderBlock = function () { 14199 var div = $('.StickyBlockHeaders').filter(':visible'); 14200 14201 if (!div.parents('.StickyBlockHeadersWrap').length) { 14202 div.wrap('<div class="StickyBlockHeadersWrap" style="position:relative;" />'); 14203 } 14204 14205 if (!div.length) { 14206 return; 14207 } 14208 14209 var currentScrollTop = $(document).scrollTop(); 14210 14211 div.each(function () { 14212 var offsetTop = $(this).offset().top; 14213 var positionTop = $(this).position().top; 14214 14215 if (offsetTop != currentScrollTop) { 14216 var top = Math.max(0, currentScrollTop - (offsetTop - positionTop)); 14217 $(this).css('top', top + 'px'); 14218 } 14219 });
14220}; 14221 14222$(document).on('scroll', followHeaderBlock); 14223 14224 14225var SmpToolTip = { 14226 HideTipsId: 0, 14227 HideTips: function (skipID) { 14228 clearTimeout(SmpToolTip.HideTipsId); 14229 //$('.SmpToolTip:visible').each(function () { if ($(this).data('realParent')) { $(this).appendTo($(this).data('realParent')) } }); 14230 $('.SmpToolTip') 14231 .filter(function () { return ($(this).attr('id') != skipID); }) 14232 .hide(0) 14233 .each(function () { 14234 $($(this).attr("targetclientid")).removeClass($(this).attr('targetcsson')); 14235 }); 14236 }, 14237 14238 Position: function (jqTarget, jqTipID) { 14239 var tipJQ = $('#' + jqTipID); 14240 var wasVisible = tipJQ.is(':visible'); 14241 SmpToolTip.HideTips(jqTipID); 14242 14243 if (!wasVisible) { 14244 jqTarget.addClass(tipJQ.attr('targetcsson')); 14245 var targetPosition = jqTarget.offset(); 14246 14247 var maxLeft = $(document).width() - tipJQ.width() - 30; //note: document instead of window for mobile viewport 14248 var maxTop = $(document).height() - tipJQ.height() - 30; //note: document instead of window for mobile viewport 14249 14250 if (!('ontouchstart' in window)) { 14251 maxTop = Math.min(maxTop, $(window).height() + $(window).scrollTop() - tipJQ.height() - 30); 14252 } 14253 14254 tipJQ.css({ 14255 'top': Math.min(maxTop, targetPosition.top + jqTarget.outerHeight(false) + 5 - $(window).scrollTop()) + 'px', 14256 'left': Math.min(maxLeft, targetPosition.left - tipJQ.width() / 2 + jqTarget.outerWidth(false) / 2) + 'px', 14257 'max-width': $(document).width() / 2 + 'px', 14258 'position': 'fixed' 14259 }); 14260 14261 jqTarget.off('mouseenter').on('mouseenter', function () { clearTimeout(SmpToolTip.HideTipsId) }); 14262 jqTarget.off('mouseleave').on('mouseleave', function () { SmpToolTip.HideTipsId = setTimeout(SmpToolTip.HideTips, 500) }); 14263 14264 tipJQ.off('mouseenter').on('mouseenter', function () { clearTimeout(SmpToolTip.HideTipsId) }); 14265 tipJQ.off('mouseleave').on('mouseleave', function () { SmpToolTip.HideTipsId = setTimeout(SmpToolTip.HideTips, 500) }); 14266 } 14267 return (tipJQ); 14268 }, 14269 Initialize: function () { 14270 $(function () { 14271 $(window).on("resize", SmpToolTip.HideTips); 14272 }) 14273 } 14274}; 14275 14276SmpToolTip.Initialize(); 14277 14278 14279//http://stackoverflow.com/questions/985272/jquery-selecting-text-in-an-element-akin-to-highlighting-with-your-mouse 14280function selectText(elementID) { 14281 var doc = document; 14282 var text = doc.getElementById(elementID); 14283 14284 if (doc.body.createTextRange) { // ms 14285 var range = doc.body.createTextRange(); 14286 range.moveToElementText(text); 14287 range.select(); 14288 } else if (window.getSelection) { // moz, opera, webkit 14289 var selection = window.getSelection(); 14290 var range = doc.createRange(); 14291 range.selectNodeContents(text); 14292 selection.removeAllRanges(); 14293 selection.addRange(range); 14294 } 14295} 14296 14297String.prototype.toPercent = function (digits, min, max) { 14298 return (this.toNumber(min, max).toFixed(digits != null ? digits : 2) + '%'); 14299}; 14300String.prototype.toCurrency = function (digits, min, max) { 14301 var fixedString = this.toNumber(min, max).toFixed(digits != null ? digits : 2); 14302 if(fixedString.match(/^-/gi) && !fixedString.match(/[1-9]/gi)){ 14303 fixedString = fixedString.split('').slice(1).join(''); 14304 } 14305 14306 return ( "$" + fixedString.replace( /\B(?=(\d{3})+(?!\d))/g, "," ) ); 14307}; 14308String.prototype.toNumber = function (min, max) { 14309 if (!this) { 14310 return (min != null ? min : 0); 14311 } 14312 14313 var n = parseFloat(String(this).replace(/[^0-9.\-e]/gi, "")); 14314 n = isNaN(n) ? 0 : n; 14315 n = min != null ? Math.max(min, n) : n; 14316 n = max != null ? Math.min(max, n) : n; 14317 return (n); 14318}; 14319Number.prototype.toNumber = function () { 14320 return (this); 14321}; 14322String.prototype.toTimeSpan = function () { 14323 if (this) { 14324 var m = moment(String(this), "h:mm A"); 14325 if (m) { 14326 return (m.format("H:mm"));
14327 } 14328 } 14329 return ("00:00:00"); 14330}; 14331String.prototype.toMomentDate = function () { 14332 if (this) { 14333 var value = String(this); 14334 var d = moment(value); 14335 14336 switch (value.toLowerCase()) { 14337 case 'today': 14338 d = moment(); 14339 break; 14340 case 'tomorrow': 14341 d = moment().add('d', 1); 14342 break; 14343 case 'yesterday': 14344 d = moment().add('d', -1); 14345 break; 14346 } 14347 14348 if (!d || !d.date()) { 14349 d = moment(value, 'M/D'); 14350 } 14351 if (d && d.year() < new Date().getFullYear() - 80) { 14352 if (d.year() == 1900) { 14353 d.year(moment().year()); //no year entered 14354 } 14355 else { 14356 d.add('y', 100); //2 digit year entered 14357 } 14358 } 14359 if (d) { 14360 return (d); 14361 } 14362 } 14363 return (null); 14364}; 14365 14366 14367function initNumericTextBoxes() { 14368 $("body").on("change", "input[data-behavior~='NumericTextBox']", function () { 14369 const $input = $(this); 14370 if ($input.val().replace(/\W/gi, '') == '') { 14371 $input.val(''); 14372 return; 14373 } 14374 14375 let opts = { 14376 min: $input.attr("data-minvalue") || 0, 14377 max: $input.attr("data-maxvalue") || Number.MAX_VALUE, 14378 type: $input.attr("data-type") || 'number', 14379 digits: $input.attr("data-decimaldigits") || 0, 14380 autocorrect: $input.attr("data-autocorrect") || 'true', 14381 plusAndMinusVisible: $input.attr("data-plus-and-minus-visible") || false, 14382 }; 14383 14384 let numericValue; 14385 let value = $input.val().trim(); 14386 14387 if (opts.type.toLowerCase() == 'number') 14388 numericValue = value.toNumber(opts.min, opts.max).toFixed(opts.digits != null ? parseInt(opts.digits, 10) : 2); 14389 else if (opts.type.toLowerCase() == 'percent') 14390 numericValue = value.toPercent(opts.digits, opts.min, opts.max); 14391 else if (opts.type.toLowerCase() == 'currency') 14392 numericValue = value.toCurrency(opts.digits, opts.min, opts.max); 14393 14394 // If autocorrect is false than we perform validation without replacing the value 14395 if (opts.autocorrect.toLowerCase() !== 'false') { 14396 $input.val(numericValue); 14397 } else { 14398 if (numericValue !== value) { 14399 const parent = $input.parent(); 14400 parent.find('span.error').remove(); 14401 parent.prepend('<span class="validated-input-hint error">' + $input.siblings('.validated-input-hint').text() + '</span>'); 14402 } else { 14403 $input.css('border-color', 'revert'); 14404 $input.parent().find('span.error').first().remove(); 14405 } 14406 } 14407 14408 if (opts.plusAndMinusVisible) { 14409 $input.parent().find('.decrement').prop('disabled', numericValue <= Number(opts.min)); 14410 $input.parent().find('.increment').prop('disabled', numericValue >= Number(opts.max)); 14411 } 14412 }); 14413 14414 $("input[data-behavior~='NumericTextBox']").each(function () { 14415 const $input = $(this); 14416 14417 const changeQty = (diff) => { 14418 $input.val(Number($input.val()) + diff).trigger('change'); 14419 }; 14420 14421 if ($input.attr("data-plus-and-minus-visible")) { 14422 const $wrapper = $(`<span class="numeric-text-box-wrapper" />`); 14423 $input.wrap($wrapper) 14424 $input.addClass("grit-input"); 14425 const $decrementButton = $(`<button type="button" class="decrement"><i class="fa fa-minus"></i></button>`); 14426 const $incrementButton = $(`<button type="button" class="increment"><i class="fa fa-plus"></i></button>`); 14427 14428 $decrementButton.insertBefore($input); 14429 $incrementButton.insertAfter($input); 14430 14431 $incrementButton.on('click', () => changeQty(1)); 14432 $decrementButton.on('click', () => changeQty(-1)); 14433 setTimeout(() => $input.trigger('change'), 250); 14434 } 14435 });
14436} 14437$(function () { 14438 initNumericTextBoxes(); 14439}) 14440 14441$( function () 14442{ 14443 if( $.fn.miniColors ) 14444 { 14445 $( '.ColorPicker' ).miniColors(); 14446 } 14447} ); 14448 14449function distinctFilter( value, index, self ) 14450{ 14451 return ( self.indexOf( value ) === index ); 14452} 14453 14454var DateTimeRange = function ( start, end ) 14455{ 14456 var me = { 14457 Start: start, 14458 End: end, 14459 Same: function ( range2 ) 14460 { 14461 return ( me.Start == range2.Start && me.End == range2.End ); 14462 }, 14463 Contains: function ( inner ) 14464 { 14465 return ( !me.Same( inner ) && me.Start <= inner.Start && me.End >= inner.End ); 14466 }, 14467 Overlaps: function ( range2 ) 14468 { 14469 return ( 14470 me.Same( range2 ) 14471 || me.Contains( range2 ) 14472 || range2.Contains( me ) 14473 || me.Start < range2.Start && me.End > range2.Start 14474 || range2.Start < me.Start && range2.End > me.Start 14475 ); 14476 }, 14477 Subtract: function ( range2 ) 14478 { 14479 var result = [] 14480 if( me.Same( range2 ) ) 14481 return ( result ); //none 14482 if( range2.Contains( me ) ) 14483 return ( result ); //none 14484 14485 return ( $.Enumerable.From( [new DateTimeRange( me.Start, range2.Start ), 14486 new DateTimeRange( range2.End, me.End )] ) 14487 .Where( "$.End > $.Start" ) 14488 .ToArray() ); 14489 } 14490 }; 14491 14492 return ( me ); 14493}; 14494DateTimeRange.Sum = function(ranges) 14495{ 14496 var ordered = $.Enumerable.From(ranges).OrderBy("$.Start").ToArray(); 14497 14498 var summed = []; 14499 14500 for (var i in ordered) 14501 { 14502 var item = ordered[i]; 14503 var overlappingEnd = 14504 $.Enumerable.From(ordered) 14505 .Where(function (a) { return (item.Overlaps(a) || item.Contains(a) || a.Contains(item) || item.End == a.Start); }) 14506 .OrderBy("$.End") 14507 .Select("$.End"); 14508 14509 if (overlappingEnd.Any()) 14510 { 14511 var newRange = DateTimeRange(item.Start, overlappingEnd.Last()); 14512 14513 var overlappingSum = 14514 $.Enumerable.From(summed) 14515 .Where(function (a) { return (a.Overlaps(newRange) || item.Contains(newRange) || a.End == newRange.Start); }) 14516 .ToArray(); 14517 14518 if (overlappingSum.length) 14519 { 14520 if ($.Enumerable.From(overlappingSum).Max("$.End") < newRange.End) 14521 overlappingSum[overlappingSum.length - 1].End = newRange.End; 14522 } 14523 else 14524 { 14525 summed.push(newRange); 14526 } 14527 } 14528 else 14529 { 14530 summed.push(item); 14531 } 14532 } 14533 14534 return (summed); 14535}; 14536 14537 14538SMP.Array = SMP.Array || {}; 14539SMP.Array.remove = function (array, arg) { 14540 var what, L = arg.length, ax; 14541 while (L && array.length) { 14542 what = arg[--L]; 14543 while ((ax = array.indexOf(what)) != -1) { 14544 array.splice(ax, 1); 14545 } 14546 } 14547 return (array); 14548}; 14549 14550function htmlEscape(str) { 14551 return String(str) 14552 .replace(/&/g, '&') 14553 .replace(/"/g, '"') 14554 .replace(/'/g, ''') 14555 .replace(/</g, '<') 14556 .replace(/>/g, '>'); 14557} 14558 14559$(function () { 14560 $(document).on('mouseover', '.smp-tooltip[data-smp-text]', (e) => ShowTooltip(e)); 14561 $(document).on('mouseout', '.smp-tooltip[data-smp-text]', (e) => HideTooltip(e)); 14562 14563 function ShowTooltip(event) { 14564 const tooltipPanel = document.createElement('span'); 14565 const tooltipText = event.target.getAttribute('data-smp-text') || ''; 14566 const isWider = event.target.classList.contains('wider-tooltip') || tooltipText.length > 60; 14567 tooltipPanel.className = 'tooltip-panel ' + (isWider ? ' wider-tooltip': ''); 14568 tooltipPanel.innerHTML = tooltipText; 14569 14570 event.target.setAttribute('data-smp-text', ''); 14571 document.body.appendChild(tooltipPanel); 14572 event.target._tooltipRef = tooltipPanel; 14573 14574 const panelWidth = isWider ? 360 : 180; 14575 const tipIconWidth = 24; 14576 14577 //transform tooltip 14578 const tipIcon = event.target.getBoundingClientRect(); 14579 const tooltipHeight = tooltipPanel.getBoundingClientRect().height; 14580 const windowRect = document.body.getBoundingClientRect(); 14581 const windowRightX = windowRect.x + windowRect.width; 14582 14583 const xTransform = tipIcon.x < 0 14584 ? 0 14585 : tipIcon.x + panelWidth > windowRightX 14586 ? windowRightX - panelWidth 14587 : tipIcon.x + tipIconWidth; 14588 14589 const yTransform = tipIcon.y + tooltipHeight > window.innerHeight 14590 ? window.innerHeight + window.scrollY - tooltipHeight 14591 : tipIcon.y - windowRect.y; 14592 14593 tooltipPanel.style.position = 'absolute'; 14594 tooltipPanel.style.left = `${xTransform}px`; 14595 tooltipPanel.style.top = `${yTransform}px`; 14596 } 14597 14598 function HideTooltip(event) { 14599 event.target.setAttribute('data-smp-text', event.target._tooltipRef.innerHTML); 14600 document.body.removeChild(event.target._tooltipRef); 14601 } 14602}); 14603 14604$(function () { 14605 $(document).on('mouseover', '.tooltip[data-tooltip-text]', (e) => ShowGritTooltip(e)); 14606 $(document).on('mouseout', '.tooltip[data-tooltip-text]', (e) => onMouseOut(e)); 14607 14608 function triggerWasRemoved(node, triggerEl) { 14609 if (node === triggerEl) return true; 14610 if (node.nodeType === 1 && typeof node.contains === 'function' && node.contains(triggerEl)) return true; 14611 return false; 14612 } 14613 14614 function ShowGritTooltip(event) { 14615 const trigger = event.currentTarget; 14616 const text = trigger.getAttribute('data-tooltip-text'); 14617 if (!text || trigger._gritTooltipRef) return; 14618 14619 const panel = document.createElement('span'); 14620 panel.className = 'tiptext'; 14621 if (trigger.classList.contains('arrow')) panel.classList.add('arrow'); 14622 14623 const direction = ['bottom', 'left', 'right'].find(d => trigger.classList.contains(d)) || 'top'; 14624 if (direction !== 'top') panel.classList.add(direction); 14625 14626 panel.textContent = text; 14627 panel.style.position = 'fixed'; 14628 14629 const panelWrapper = document.createElement('span'); 14630 panelWrapper.className = 'grit-theme'; 14631 panelWrapper.appendChild(panel); 14632 14633 document.body.appendChild(panelWrapper); 14634 trigger._gritTooltipRef = panelWrapper; 14635 14636 const triggerRect = trigger.getBoundingClientRect(); 14637 const panelRect = panel.getBoundingClientRect(); 14638 const tooltipSpacing = 8; 14639 const arrowSize = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--tooltip-arrow-size')) || 6; 14640 const viewportEdgeMargin = 4; 14641 const gap = tooltipSpacing + arrowSize; 14642 14643 let top, left; 14644 if (direction === 'top') { 14645 top = triggerRect.top - panelRect.height - gap; 14646 left = triggerRect.left + triggerRect.width / 2 - panelRect.width / 2; 14647 } else if (direction === 'bottom') { 14648 top = triggerRect.bottom + gap; 14649 left = triggerRect.left + triggerRect.width / 2 - panelRect.width / 2; 14650 } else if (direction === 'left') { 14651 top = triggerRect.top + triggerRect.height / 2 - panelRect.height / 2; 14652 left = triggerRect.left - panelRect.width - gap; 14653 } else { 14654 top = triggerRect.top + triggerRect.height / 2 - panelRect.height / 2;
14655 left = triggerRect.right + gap; 14656 } 14657 14658 left = Math.max(viewportEdgeMargin, Math.min(left, window.innerWidth - panelRect.width - viewportEdgeMargin)); 14659 top = Math.max(viewportEdgeMargin, Math.min(top, window.innerHeight - panelRect.height - viewportEdgeMargin)); 14660 14661 panel.style.top = `${top}px`; 14662 panel.style.left = `${left}px`; 14663 14664 requestAnimationFrame(() => panel.classList.add('visible')); 14665 14666 const observer = new MutationObserver((mutations) => { 14667 mutations.forEach((mutation) => { 14668 mutation.removedNodes.forEach((node) => { 14669 if (triggerWasRemoved(node, trigger)) { 14670 HideGritTooltip(trigger, panelWrapper); 14671 } 14672 }) 14673 }); 14674 }); 14675 trigger._observer = observer; 14676 observer.observe(document.body, { subtree: true, childList: true }); 14677 } 14678 14679 function onMouseOut(event) { 14680 const trigger = event.currentTarget; 14681 const wrapper = trigger._gritTooltipRef; 14682 if (wrapper || trigger._observer) { 14683 HideGritTooltip(trigger, wrapper); 14684 } 14685 } 14686 14687 function HideGritTooltip(trigger, wrapper) { 14688 trigger._gritTooltipRef = null; 14689 trigger._observer?.disconnect(); 14690 trigger._observer = null; 14691 if (!wrapper) return; 14692 const panel = wrapper.querySelector('.tiptext') || wrapper; 14693 panel.classList.remove('visible'); 14694 let removed = false; 14695 const done = () => { 14696 if (removed) return; 14697 removed = true; 14698 wrapper.remove(); 14699 }; 14700 panel.addEventListener('transitionend', done, { once: true }); 14701 setTimeout(done, 500); 14702 } 14703}); 14704 14705$(function () { 14706 14707 $('[download-warning-trigger]').each(function () { 14708 const onClick = $(this).attr('onclick'); 14709 if (onClick) { 14710 $(this).removeAttr('onclick').attr('download-warning-postback', onClick); 14711 } 14712 }); 14713 14714 $(document).on('click', '[download-warning-trigger]', function (e) { 14715 e.preventDefault(); 14716 e.stopImmediatePropagation(); 14717 14718 const name = this.id.replace(/_/g, '$'); 14719 const toEval = $(this).attr('download-warning-postback'); 14720 14721 $.fn.modalConfirm.open({ 14722 title: 'Privacy Restricted', 14723 content: 'In order to protect the privacy of our clients, an administrator will be notified if you export this content. Agree to continue?', 14724 confirm: () => { 14725 $(this).removeAttr('download-warning-trigger'); 14726 if (toEval) { 14727 eval(toEval); 14728 } else { 14729 __doPostBack(name, ''); 14730 } 14731 } 14732 }); 14733 14734 return false; 14735 }); 14736 14737 $('[smp-post-on-confirm], [grit-post-on-confirm]').each(function () { 14738 let onClick = $(this).attr('onclick'); 14739 14740 const hideOnClick = $(this).attr('smp-hide-on-click'); 14741 if (hideOnClick !== undefined) { 14742 $(this).removeAttr('smp-hide-on-click'); 14743 onClick += ';window.smpHideOnClick(this);'; 14744 } 14745 14746 $(this).removeAttr('onclick').attr('smp-post-on-confirm-eval', onClick); 14747 }); 14748 14749 $(document).on('change', '[smp-upload-change]', function () { 14750 // Grab an existing success badge sibling element, if one exists 14751 const $successBadge = $(this).siblings('[smp-success-badge]'); 14752 const hasSuccessBadge = $successBadge.length; 14753 const hasFiles = this.files.length; 14754 // If there is a file in the upload field and no badge has been added already, insert the success badge 14755 if (hasFiles && !hasSuccessBadge) { 14756 $(this).after('<i class="fa fa-check-circle success" smp-success-badge></i>'); 14757 } else if (!hasFiles && hasSuccessBadge) { 14758 // If there are no files in the upload field and there was a success badge, simply remove it 14759 $successBadge.remove(); 14760 } 14761 }); 14762 14763 $('[grit-post-on-confirm]').on('click', function () { 14764 const name = this.id.replace(/_/g, '$'); // doesn't work with clientidmode='static' 14765 const toEval = $(this).attr('smp-post-on-confirm-eval'); 14766 14767 $.fn.openGritModal({ 14768 title: 'Confirm', 14769 target: `<span><div class="p-4">${$(this).attr('grit-post-on-confirm')}</div><span>`, 14770 onSubmit: () => { 14771 const disableButton = () => { 14772 $(this).removeAttr('grit-post-on-confirm') 14773 .prop('disabled', true) 14774 .prop('enabled', false); 14775 }; 14776 14777 if (toEval) { 14778 if (toEval.match(/Page_ClientValidate/) 14779 && typeof (Page_ClientValidate) == 'function' 14780 && Page_ClientValidate($(this).attr('validationgroup') || '')) { 14781 disableButton(); 14782 } 14783 14784 eval(toEval); 14785 } 14786 else { 14787 disableButton(); 14788 __doPostBack(name, ''); 14789 } 14790 }, 14791 submitText: 'Yes', 14792 cancelText: 'No' 14793 }) 14794 });
14795 14796 $(document).on('click', '[smp-post-on-confirm]', function () { 14797 const name = this.id.replace(/_/g, '$'); // doesn't work with clientidmode='static' 14798 const toEval = $(this).attr('smp-post-on-confirm-eval'); 14799 14800 let cssClass = $(this).attr('smp-post-on-confirm-class') || ''; 14801 14802 if (!cssClass) { 14803 const parts = $(this).attr('smp-post-on-confirm').split(':'); 14804 if (parts.length) { 14805 cssClass = parts[0].toLowerCase(); 14806 } 14807 } 14808 14809 $.fn.modalConfirm.open({ 14810 content: $(this).attr('smp-post-on-confirm') || 'Are you sure?', 14811 cssClass, 14812 confirm: () => { 14813 const disableButton = () => { 14814 $(this).removeAttr('smp-post-on-confirm') 14815 .prop('disabled', true) 14816 .prop('enabled', false); 14817 }; 14818 14819 if (toEval) { 14820 if (toEval.match(/Page_ClientValidate/) 14821 && typeof (Page_ClientValidate) == 'function' 14822 && Page_ClientValidate($(this).attr('validationgroup') || '')) { 14823 disableButton(); 14824 } 14825 14826 eval(toEval); 14827 } 14828 else { 14829 disableButton(); 14830 __doPostBack(name, ''); 14831 } 14832 } 14833 }); 14834 14835 return false; 14836 }); 14837 14838 $('[smp-default-button]').on('keypress', 'input, select', function (e) { 14839 if (e.which === 13) { 14840 const $target = $(e.target); 14841 if ($target.closest('.ck-editor').length > 0) { 14842 return true; 14843 } 14844 14845 const $panel = $(e.currentTarget); 14846 $panel.find($panel.attr('smp-default-button') || 'button').not('.ck-editor button').trigger('click'); 14847 14848 return false; 14849 } 14850 }); 14851 14852 $('[smp-track-media-view]').on('click', function (e) { 14853 const mediaId = $(this).attr('mediaid'); 14854 const profileId = $(this).attr('profileid'); 14855 const isContact = !!$(this).attr('iscontact'); 14856 SMP.trackMediaView({ profileId, mediaId, isContact }); 14857 }); 14858}); 14859 14860SMP.trackMediaView = function ({ profileId, mediaId, isContact }) { 14861 fetch(`/api/profile/${profileId}/view`, { 14862 method: "POST", 14863 headers: { 14864 'Content-Type': 'application/json' 14865 }, 14866 body: JSON.stringify({ mediaId, isContact }) 14867 }); 14868}; 14869 14870SMP.autoScrollTable = function autoScrollTable( 14871 childElement, 14872 nonScrollVerticalAreaDecimal = .75, 14873 nonScrollHorizontalAreaDecimal = .9, 14874 scrollByObject = { top: 125, left: 0, behavior: 'smooth' }) 14875{ 14876 const table = $(childElement).get(0).closest('table'); 14877 const tableBottom = $(table).offset().top + $(table).height(); 14878 const childBottom = $(childElement).offset().top + $(childElement).height(); 14879 const tableRight = $(table).offset().left + $(table).width(); 14880 const childRight = $(childElement).offset().left + $(childElement).width(); 14881 14882 table.scrollBy({ 14883 top: childBottom > tableBottom * nonScrollVerticalAreaDecimal ? scrollByObject.top : 0, 14884 left: childRight > tableRight * nonScrollHorizontalAreaDecimal ? scrollByObject.left : 0, 14885 behavior: 'smooth' }); 14886} 14887 14888SMP.beep = function beep(duration, frequency, volume, type, callback) { 14889 var audioCtx = new (window.AudioContext || window.webkitAudioContext || window.audioContext); 14890 var oscillator = audioCtx.createOscillator(); 14891 var gainNode = audioCtx.createGain(); 14892 14893 oscillator.connect(gainNode); 14894 gainNode.connect(audioCtx.destination); 14895 14896 if (volume) { gainNode.gain.value = volume; }; 14897 if (frequency) { oscillator.frequency.value = frequency; } 14898 if (type) { oscillator.type = type; } 14899 if (callback) { oscillator.onended = callback; } 14900 14901 oscillator.start(); 14902 setTimeout(function () { oscillator.stop() }, (duration ? duration : 250)); 14903}; 14904 14905SMP.fillCameraSelection = 14906 async function(windowContext, $cameraSelector, permissionsPointer) { 14907 const devices = await windowContext.navigator.mediaDevices.enumerateDevices(); 14908 const videoDevices = devices.filter(device => device.kind === 'videoinput' && !!device.deviceId); 14909 const options = videoDevices.map(videoDevice => { 14910 return `<option value="${videoDevice.deviceId}">${videoDevice.label || 'Default Camera'}</option>`; 14911 }); 14912 14913 $cameraSelector.html(options.join(''));
14914 14915 if (!videoDevices.length && !permissionsPointer) { 14916 permissionsPointer = true; 14917 windowContext.navigator.mediaDevices.getUserMedia({ video: true }) 14918 .then(SMP.fillCameraSelection); 14919 } 14920 }; 14921 14922SMP.addPlayerPhoto = 14923 async function(windowContext, profileId, callingElement, videoPointer, $cameraSelector, $saveButton, selectionPreFilled = true) { 14924 if (!selectionPreFilled) { 14925 await SMP.fillCameraSelection(windowContext, $cameraSelector, callingElement); 14926 $.fn.modalElement.open({ target: '#CameraPreview' }); 14927 } 14928 14929 videoPointer.pause(); 14930 videoPointer.srcObject = null; 14931 windowContext 14932 .navigator 14933 .mediaDevices 14934 .getUserMedia({ 14935 video: { 14936 width: 1280, 14937 height: 720, 14938 deviceId: { 14939 exact: $cameraSelector.val() 14940 } 14941 } 14942 }) 14943 .then(stream => { 14944 videoPointer.srcObject = stream; 14945 videoPointer.play(); 14946 $.fn.modalElement.open({ target: "#CameraPreview" }); 14947 }); 14948 14949 const saveImage = () => { 14950 const canvas = document.createElement("canvas"); 14951 const context2D = canvas.getContext("2d"); 14952 canvas.width = videoPointer.videoWidth; 14953 canvas.height = videoPointer.videoHeight; 14954 context2D.drawImage(videoPointer, 0, 0, videoPointer.videoWidth, videoPointer.videoHeight); 14955 14956 $.fn.modalElement.close(); 14957 14958 fetch(`/api/profile/${profileId}/image`, { 14959 method: 'POST', 14960 headers: { 14961 'Content-Type': 'application/json' 14962 }, 14963 body: JSON.stringify({ imageDataUri: canvas.toDataURL("image/jpeg")}) 14964 }) 14965 .then(res => { 14966 if (!res.ok) return alert('Error saving'); 14967 $(callingElement).replaceWith(`<img alt="athlete profile photo" class="circle-image" src="${canvas.toDataURL("image/jpeg")}" />`); 14968 $.fn.modalElement.open({ target: "#AddPhotoSuccess" }); 14969 }) 14970 .catch(() => $.fn.modalElement.open({ target: "#AddPhotoFailure" })); 14971 }; 14972 14973 $saveButton.off('click').on('click', saveImage); 14974 }; 14975 14976SMP.validateJersey = function (event) { 14977 if (event.type === "keypress") { 14978 if (event.charCode < 48 || event.charCode > 57) { 14979 return false; 14980 } 14981 } else if (event.type === "paste") { 14982 event.preventDefault(); 14983 const pastedData = (event.clipboardData || window.clipboardData || event.originalEvent.clipboardData).getData('text'); 14984 if (!/^\d*$/.test(pastedData) || pastedData.length > 3) { 14985 return false; 14986 } 14987 } else if (event.type === "input" || event.type === "change") { 14988 const inputValue = event.target.value; 14989 if (!/^\d*$/.test(inputValue) || inputValue.length > 3) { 14990 return false; 14991 } 14992 } else if (event.type === "drop" || event.originalEvent.type === "drop") { 14993 const droppedEvent = (event.originalEvent || event); 14994 droppedEvent.preventDefault(); 14995 14996 let dataTransfer = droppedEvent.dataTransfer.getData("text"); 14997 if (!/^\d*$/.test(dataTransfer) || dataTransfer.length > 3) { 14998 return false; 14999 } 15000 } 15001 15002 let inputElement = event.target; 15003 inputElement.setAttribute('data-behavior', 'NumericTextBox'); 15004 inputElement.setAttribute('data-autocorrect', 'false'); 15005 inputElement.setAttribute('data-type', 'Number'); 15006 inputElement.setAttribute('min', '0'); 15007 inputElement.setAttribute('maxlength', '3'); 15008 inputElement.setAttribute('data-decimaldigits', '0'); 15009 15010 return true; 15011} 15012 15013SMP.parseCurrencyString = function (str) { 15014 if (!str) return null; 15015 15016 if (typeof str === 'string') { 15017 if (str.indexOf('$') !== -1) { 15018 return parseFloat(str.replace(/[^\d.]/g, '')); 15019 } 15020 } 15021 15022 return str; 15023} 15024 15025SMP.createTempCurrencyValue = function (num) { 15026 const currInst = new Intl.NumberFormat('en-US', { 15027 style: 'currency', 15028 currency: 'USD' 15029 });
15030 15031 if (!num || Number.isNaN(num)) return ""; 15032 if (num == 0) return "$0.00"; 15033 15034 return currInst.format(Number(num)); 15035} 15036 15037SMP.calculateFinancialBudget = function (target, divisionCost, programCost, teamsWithCostAvg, teamsWithCostCount, teamsWithoutCostCount, statBudget, isTryoutDivision) { 15038 if (!statBudget) { 15039 return; 15040 } 15041 15042 const costForDivision = parseInt(SMP.parseCurrencyString(divisionCost) 15043 || SMP.parseCurrencyString(programCost)); 15044 15045 let avgCost = 0; 15046 let divisor = 0; 15047 let val; 15048 15049 // only divisions with tryouts we care about team cost (accepting roster spots) 15050 if (isTryoutDivision == 'True') { 15051 if (!Number.isNaN(teamsWithCostAvg)) { 15052 avgCost += teamsWithCostAvg * teamsWithCostCount; 15053 divisor += teamsWithCostCount; 15054 } 15055 if (!Number.isNaN(costForDivision)) { 15056 avgCost += costForDivision * teamsWithoutCostCount; 15057 divisor += teamsWithoutCostCount; 15058 } 15059 15060 if (typeof avgCost === 'number') { 15061 avgCost = avgCost / divisor; 15062 val = (avgCost * statBudget).toFixed(2); 15063 } 15064 } 15065 15066 try { 15067 val = Number(val); 15068 } catch (e) {} 15069 15070 if (Number.isNaN(val)) { 15071 val = (costForDivision * statBudget).toFixed(2); 15072 } 15073 15074 // opposit of above if statement, but is present for catching NaN 15075 if (typeof Number(val) !== 'number') { 15076 // in some cases people don't have ANY cost, even a program cost, which obviously is needed for this. 15077 $.fn.modalAlert.open({ content: "There is no available cost we can use to calculate financial budget." }); 15078 } else { 15079 target.val(val); 15080 target.val(SMP.createTempCurrencyValue(target.val())); 15081 } 15082} 15083 15084SMP.toggleDashboard = ctx => { 15085 const $target = $(ctx) 15086 .closest('.card.no-flex') 15087 const xIcon = 'fa-xmark'; 15088 const arrowIcon = 'fa-chevron-down'; 15089 15090 $target 15091 .closest('.dashboard-container') 15092 .toggleClass('dash-hidden'); 15093 15094 $(ctx).children().toggleClass([xIcon, arrowIcon]); 15095}; 15096 15097SMP.validateDateString = function (str) { 15098 const allowedDateFormats = [ 15099 "M/D/YYYY", 15100 "M/DD/YYYY", 15101 "MM/D/YYYY", 15102 "MM/DD/YYYY", 15103 "M/D/YY", 15104 "M/DD/YY", 15105 "MM/D/YY", 15106 "MM/DD/YY" 15107 ]; 15108 15109 try { 15110 return moment(str, allowedDateFormats, true).isValid(); 15111 } catch { 15112 return false; 15113 } 15114} 15115 15116//Below is example of usage of the following dropdown methods. Note you only need to attach the ToggleDropdown method to the onclick of each button/link INCLUDING the 'show dropdown menu' button 15117//<span class="dropdown-menu"> 15118// <button id="OptionsButton" title="Show Dropdown Menu" type="button" class="ForwardButton menu-button" 15119// onclick="ToggleDropdown('OptionsMenu', 'OptionsButton')"><i class="fa-solid fa-ellipsis"></i></button> 15120// <span id="OptionsMenu" class="menu-modal" hidden> 15121// <a title="Example Link" class="ForwardButton" 15122// href="/util/admin/programs/registration-details" target="_blank" 15123// onclick="ToggleDropdown('OptionsMenu','OptionsButton', false)">Example Link <i class='fa-solid fa-arrow-up-right-from-square'></i></a> 15124// <button type="button" title="Example Button" class="ForwardButton" runat="server" id="ExampleButton" 15125// onclick="ToggleDropdown('OptionsMenu','OptionsButton', false)">Example Button</button> 15126// </span> 15127//</span > 15128function ToggleDropdown(dropdownMenuId, dropdownButtonId, state) { //leave state undefined for the 'show dropdown menu' button, set false for dropdown items 15129 var dropdownMenu = document.getElementById(dropdownMenuId); 15130 dropdownMenu.hidden = (state !== undefined ? !state : !dropdownMenu.hidden); 15131 (dropdownMenu.hidden !== true ? 15132 window.addEventListener('click', closeHandler = CloseDropdown.bind(event, dropdownMenu, dropdownButtonId), false) : 15133 window.removeEventListener('click', closeHandler, false)) 15134} 15135 15136function CloseDropdown(dropdownMenu, dropdownButtonId, event) { 15137 var dropdownButton = document.getElementById(dropdownButtonId); 15138 if (!dropdownMenu.hidden && !dropdownMenu.contains(event.target) && !dropdownButton.contains(event.target)) { 15139 ToggleDropdown(dropdownMenu.id, dropdownButtonId, false); 15140 } 15141} 15142 15143function configureImageSelector({ clientId }) { 15144 const $input = $(`#${clientId}`); 15145 15146 if ($input.length === 0) { 15147 console.warn(`${input} not found`); 15148 return; 15149 } 15150 15151 const insertFunctionName = `insertTo${clientId}`; 15152 const $imageSelector = $(`<div 15153 class='image-selector' 15154 smp-frame-src='/views/dialog/FileManager/?type=image&insert=${encodeURI(`(window.top.opener?window.top.opener:window.top)["${insertFunctionName}"](fileName)`)}' 15155 style='background-image: url(${$input.val()})' 15156 ></div>`); 15157 15158 $imageSelector.insertAfter($input); 15159 15160 window[insertFunctionName] = (fileName) => { 15161 $input.val(fileName); 15162 $imageSelector.css('background-image', `url("${fileName}")`); 15163 $.fn.modalFrame.close(); 15164 }; 15165} 15166 15167SMP.significantDigits = { 15168 format: function (num) { 15169 15170 function maxThreeSignificantDigits(num) { 15171 let i = Math.log(num); 15172 i = Math.max(0, i - 2); 15173 i = Math.pow(10, i); 15174 return num / i * i; 15175 } 15176 15177 num = maxThreeSignificantDigits(num); 15178 15179 if (num >= 100000000) 15180 return (num / 1000000).toFixed(0) + 'M'; 15181 if (num >= 1000000) 15182 return (num / 1000000).toFixed(2) + 'M'; 15183 if (num >= 100000) 15184 return (num / 1000).toFixed(0) + 'K'; 15185 if (num >= 10000) 15186 return (num / 1000).toFixed(1) + 'K'; 15187 if (num >= 1000) 15188 return (num / 1000).toFixed(2) + 'K'; 15189
15190 return num.toLocaleString(); 15191 } 15192}; 15193 15194$(function () { 15195 $('[autocomplete=tel-area-code]').on('paste', function (e) { 15196 let number = (e.originalEvent.clipboardData || window.clipboardData).getData("text"); 15197 const phoneDiv = $(this).closest('.PhoneDiv'); 15198 15199 if (number.length >= 10) { 15200 e.preventDefault(); 15201 15202 if (number[0] === '1') { 15203 number = number.substring(1); 15204 } 15205 15206 $(this).val(number.substring(0, 3)); 15207 phoneDiv.find('[autocomplete="tel-local-prefix"]').val(number.substring(3, 6)); 15208 phoneDiv.find('[autocomplete="tel-local-suffix"]').val(number.substring(6, 10)); 15209 phoneDiv.find('[autocomplete="tel-extension"]').val(number.substring(10)); 15210 } 15211 }); 15212 15213 window.smpHideOnClick = (button) => { 15214 const $button = $(button); 15215 // don't trigger if .net validation fails 15216 if (typeof (Page_ValidationActive) !== 'undefined' 15217 && Page_ValidationActive 15218 && !Page_ClientValidate($button.attr("ValidationGroup") || "")) { 15219 return; 15220 } 15221 15222 // remove action from all buttons and store original state 15223 $('[onclick*=__doPostBack], [smp-post-on-confirm]').each(function () { 15224 if (this !== $button.get(0)) { 15225 const $el = $(this); 15226 const originalConfirm = $el.attr('smp-post-on-confirm'); 15227 if (originalConfirm) { 15228 $el.data('original-smp-confirm', originalConfirm); 15229 } 15230 $el.removeAttr('smp-post-on-confirm').addClass('disabled'); 15231 } 15232 }); 15233 15234 $('[href*=WebForm_DoPostBack]').each(function () { 15235 if (this !== $button.get(0)) { 15236 const $el = $(this); 15237 const originalHref = $el.attr('href'); 15238 if (originalHref) { 15239 $el.data('original-href', originalHref); 15240 } 15241 $el.attr('href', ''); 15242 } 15243 }); 15244 15245 $button.addClass('disabled'); 15246 const content = $button.html(); 15247 const hideOnClickContent = $button.attr('smp-hide-on-click'); 15248 $button.html(`<i class="fa fa-spinner fa-spin"></i> ${hideOnClickContent ?? content}`); 15249 15250 $button.data('original-content', content); 15251 }; 15252 15253 window.smpToggleLoadingState = (button, enable) => { 15254 const $button = $(button); 15255 15256 if ($button.hasClass('disabled') && enable !== false || enable === true) { 15257 $button.removeClass('disabled'); 15258 $button.prop('disabled', false); 15259 $button.find('.fa-spinner').remove(); 15260 } 15261 else if(!$button.hasClass('disabled')) { 15262 $button.addClass('disabled'); 15263 $button.prop('disabled', true); 15264 15265 if ($button.find('.fa-spinner').length === 0) { 15266 $button.html(`<i class="fa fa-spinner fa-spin"></i> ${$button.html()}`); 15267 } 15268 } 15269 }; 15270 15271 $('[smp-hide-on-click]').on('click', function () { 15272 window.smpHideOnClick(this); 15273 }); 15274 15275 $('[smp-show-loader]').on('click', function () { 15276 const $button = $(this); 15277 15278 // don't trigger if .net validation fails 15279 if (typeof (Page_ValidationActive) !== 'undefined' 15280 && Page_ValidationActive 15281 && !Page_ClientValidate($button.attr("ValidationGroup") || "")) { 15282 return; 15283 } 15284 const container = $($(this).attr('smp-show-loader')); 15285 const loader = $(`<a id="LoadingGraphicAnchor"></a><div><img src="/images/icons/spinner.svg" id="LoadingGraphic" style="display:none; text-align: center; margin: auto;" /></div>`); 15286 loader.insertBefore(container); 15287 container.fadeOut(200, () => { 15288 $('#LoadingGraphic').css('display', 'block');
15289 animateToAnchor('LoadingGraphicAnchor'); 15290 }); 15291 }); 15292 15293 $(document).on('click', '.explain-platform-fee i', function () { 15294 $.fn.modalAlert.open({ 15295 title: window.PLATFORM_FEE_MODAL_TITLE, 15296 content: window.PLATFORM_FEE_MODAL_CONTENT }); 15297 return false; 15298 }); 15299}); 15300 15301/// options: { alignment, user_id, admin_indicator } 15302window.createIntercom = (props = {}) => (function () { 15303 const { alignment, user_id, admin_indicator, show } = { ...props }; 15304 15305 window.intercomSettings = { 15306 api_base: "https://api-iam.intercom.io", 15307 app_id: "nmco6eaj", 15308 hide_default_launcher: true, 15309 custom_launcher_selector: '#help-button-container', 15310 vertical_padding: 80, 15311 current_url: window.location.href, 15312 alignment: alignment, 15313 user_id: user_id, 15314 admin_indicator: admin_indicator 15315 }; 15316 15317 var w = window; 15318 var ic = w.Intercom; 15319 if (typeof ic === "function") { 15320 ic('update', w.intercomSettings); 15321 } else { 15322 var d = document; 15323 var i = function () { 15324 i.c(arguments); 15325 }; 15326 i.q = []; 15327 i.c = function (args) { 15328 i.q.push(args); 15329 }; 15330 w.Intercom = i; 15331 15332 var s = d.createElement('script'); 15333 s.type = 'text/javascript'; 15334 s.async = true; 15335 s.src = 'https://widget.intercom.io/widget/nmco6eaj'; 15336 var x = d.getElementsByTagName('script')[0]; 15337 x.parentNode.insertBefore(s, x); 15338 15339 if (show) { 15340 setTimeout(() => w.Intercom('show'), 400); 15341 } 15342 } 15343})(); 15344 15345function changeMainContentBackground(className) { 15346 const contentWrapper = $('#MainContent'); 15347 if (!contentWrapper.hasClass(className)) { 15348 contentWrapper.addClass(className); 15349 } 15350} 15351 15352 15353; 15354////pf: javascript/jquery-ui.js 15355// patch for removed method used in this ancient version of query ui 15356$.curCSS = function (element, attrib, val) { 15357 $(element).css(attrib, val); 15358}; 15359 15360/*! 15361 * jQuery UI 1.8.14 15362 * 15363 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 15364 * Dual licensed under the MIT or GPL Version 2 licenses. 15365 * http://jquery.org/license 15366 * 15367 * http://docs.jquery.com/UI 15368 */ 15369(function(c,j){function k(a,b){var d=a.nodeName.toLowerCase();if("area"===d){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&l(a)}return(/input|select|textarea|button|object/.test(d)?!a.disabled:"a"==d?a.href||b:b)&&l(a)}function l(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.14", 15370keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d=this;setTimeout(function(){c(d).focus(); 15371b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=false&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this, 15372"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"),10);if(!isNaN(b)&&b!==0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind((c.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection", 15373function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,m,n){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(m)g-=parseFloat(c.curCSS(f,"border"+this+"Width",true))||0;if(n)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight,outerWidth:c.fn.outerWidth, 15374outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c(this).css(h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c(this).css(h,d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){return k(a,!isNaN(c.attr(a,"tabindex")))},tabbable:function(a){var b=c.attr(a,"tabindex"),d=isNaN(b); 15375return(d||b>=0)&&k(a,!d)}});
15375c(function(){var a=document.body,b=a.appendChild(b=document.createElement("div"));c.extend(b.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.offsetHeight===100;c.support.selectstart="onselectstart"in b;a.removeChild(b).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&a.element[0].parentNode)for(var e= 153760;e<b.length;e++)a.options[b[e][0]]&&b[e][1].apply(a.element,d)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(a,b){if(c(a).css("overflow")==="hidden")return false;b=b&&b==="left"?"scrollLeft":"scrollTop";var d=false;if(a[b]>0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a<b+d},isOver:function(a,b,d,e,h,i){return c.ui.isOverAxis(a,d,h)&&c.ui.isOverAxis(b,e,i)}})}})(jQuery); 15377;/*! 15378 * jQuery UI Widget 1.8.14 15379 * 15380 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 15381 * Dual licensed under the MIT or GPL Version 2 licenses. 15382 * http://jquery.org/license 15383 * 15384 * http://docs.jquery.com/UI/Widget 15385 */ 15386(function(b,j){if(b.cleanData){var k=b.cleanData;b.cleanData=function(a){for(var c=0,d;(d=a[c])!=null;c++)b(d).triggerHandler("remove");k(a)}}else{var l=b.fn.remove;b.fn.remove=function(a,c){return this.each(function(){if(!c)if(!a||b.filter(a,[this]).length)b("*",this).add([this]).each(function(){b(this).triggerHandler("remove")});return l.call(b(this),a,c)})}}b.widget=function(a,c,d){var e=a.split(".")[0],f;a=a.split(".")[1];f=e+"-"+a;if(!d){d=c;c=b.Widget}b.expr[":"][f]=function(h){return!!b.data(h, 15387a)};b[e]=b[e]||{};b[e][a]=function(h,g){arguments.length&&this._createWidget(h,g)};c=new c;c.options=b.extend(true,{},c.options);b[e][a].prototype=b.extend(true,c,{namespace:e,widgetName:a,widgetEventPrefix:b[e][a].prototype.widgetEventPrefix||a,widgetBaseClass:f},d);b.widget.bridge(a,b[e][a])};b.widget.bridge=function(a,c){b.fn[a]=function(d){var e=typeof d==="string",f=Array.prototype.slice.call(arguments,1),h=this;d=!e&&f.length?b.extend.apply(null,[true,d].concat(f)):d;if(e&&d.charAt(0)==="_")return h; 15388e?this.each(function(){var g=b.data(this,a),i=g&&b.isFunction(g[d])?g[d].apply(g,f):g;if(i!==g&&i!==j){h=i;return false}}):this.each(function(){var g=b.data(this,a);g?g.option(d||{})._init():b.data(this,a,new c(d,this))});return h}};b.Widget=function(a,c){arguments.length&&this._createWidget(a,c)};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(a,c){b.data(c,this.widgetName,this);this.element=b(c);this.options=b.extend(true,{},this.options, 15389this._getCreateOptions(),a);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")}, 15390widget:function(){return this.element},option:function(a,c){var d=a;if(arguments.length===0)return b.extend({},this.options);if(typeof a==="string"){if(c===j)return this.options[a];d={};d[a]=c}this._setOptions(d);return this},_setOptions:function(a){var c=this;b.each(a,function(d,e){c._setOption(d,e)});return this},_setOption:function(a,c){this.options[a]=c;if(a==="disabled")this.widget()[c?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",c);return this}, 15391enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(a,c,d){var e=this.options[a];c=b.Event(c);c.type=(a===this.widgetEventPrefix?a:this.widgetEventPrefix+a).toLowerCase();d=d||{};if(c.originalEvent){a=b.event.props.length;for(var f;a;){f=b.event.props[--a];c[f]=c.originalEvent[f]}}this.element.trigger(c,d);return!(b.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery); 15392;/*! 15393 * jQuery UI Mouse 1.8.14 15394 * 15395 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 15396 * Dual licensed under the MIT or GPL Version 2 licenses. 15397 * http://jquery.org/license 15398 * 15399 * http://docs.jquery.com/UI/Mouse 15400 * 15401 * Depends: 15402 * jquery.ui.widget.js 15403 */ 15404(function(b){var d=false;b(document).on('mousedown', function(){d=false});b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var a=this;this.element.bind("mousedown."+this.widgetName,function(c){return a._mouseDown(c)}).bind("click."+this.widgetName,function(c){if(true===b.data(c.target,a.widgetName+".preventClickEvent")){b.removeData(c.target,a.widgetName+".preventClickEvent");c.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+ 15405this.widgetName)}
15405,_mouseDown:function(a){if(!d){this._mouseStarted&&this._mouseUp(a);this._mouseDownEvent=a;var c=this,f=a.which==1,g=typeof this.options.cancel=="string"?b(a.target).closest(this.options.cancel).length:false;if(!f||g||!this._mouseCapture(a))return true;this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet)this._mouseDelayTimer=setTimeout(function(){c.mouseDelayMet=true},this.options.delay);if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a)){this._mouseStarted=this._mouseStart(a)!== 15406false;if(!this._mouseStarted){a.preventDefault();return true}}true===b.data(a.target,this.widgetName+".preventClickEvent")&&b.removeData(a.target,this.widgetName+".preventClickEvent");this._mouseMoveDelegate=function(e){return c._mouseMove(e)};this._mouseUpDelegate=function(e){return c._mouseUp(e)};b(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);a.preventDefault();return d=true}},_mouseMove:function(a){if(false&& 15407!(document.documentMode>=9)&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted= 15408false;a.target==this._mouseDownEvent.target&&b.data(a.target,this.widgetName+".preventClickEvent",true);this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery); 15409;/* 15410 * jQuery UI Position 1.8.14 15411 * 15412 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 15413 * Dual licensed under the MIT or GPL Version 2 licenses. 15414 * http://jquery.org/license 15415 * 15416 * http://docs.jquery.com/UI/Position 15417 */ 15418(function(c){c.ui=c.ui||{};var n=/left|center|right/,o=/top|center|bottom/,t=c.fn.position,u=c.fn.offset;c.fn.position=function(b){if(!b||!b.of)return t.apply(this,arguments);b=c.extend({},b);var a=c(b.of),d=a[0],g=(b.collision||"flip").split(" "),e=b.offset?b.offset.split(" "):[0,0],h,k,j;if(d.nodeType===9){h=a.width();k=a.height();j={top:0,left:0}}else if(d.setTimeout){h=a.width();k=a.height();j={top:a.scrollTop(),left:a.scrollLeft()}}else if(d.preventDefault){b.at="left top";h=k=0;j={top:b.of.pageY, 15419left:b.of.pageX}}else{h=a.outerWidth(false);k=a.outerHeight(false);j=a.offset()}c.each(["my","at"],function(){var f=(b[this]||"").split(" ");if(f.length===1)f=n.test(f[0])?f.concat(["center"]):o.test(f[0])?["center"].concat(f):["center","center"];f[0]=n.test(f[0])?f[0]:"center";f[1]=o.test(f[1])?f[1]:"center";b[this]=f});if(g.length===1)g[1]=g[0];e[0]=parseInt(e[0],10)||0;if(e.length===1)e[1]=e[0];e[1]=parseInt(e[1],10)||0;if(b.at[0]==="right")j.left+=h;else if(b.at[0]==="center")j.left+=h/2;if(b.at[1]==="bottom")j.top+= 15420k;else if(b.at[1]==="center")j.top+=k/2;j.left+=e[0];j.top+=e[1];return this.each(function(){var f=c(this),l=f.outerWidth(false),m=f.outerHeight(false),p=parseInt(c.curCSS(this,"marginLeft",true))||0,q=parseInt(c.curCSS(this,"marginTop",true))||0,v=l+p+(parseInt(c.curCSS(this,"marginRight",true))||0),w=m+q+(parseInt(c.curCSS(this,"marginBottom",true))||0),i=c.extend({},j),r;if(b.my[0]==="right")i.left-=l;else if(b.my[0]==="center")i.left-=l/2;if(b.my[1]==="bottom")i.top-=m;else if(b.my[1]==="center")i.top-= 15421m/2;i.left=Math.round(i.left);i.top=Math.round(i.top);r={left:i.left-p,top:i.top-q};c.each(["left","top"],function(s,x){c.ui.position[g[s]]&&c.ui.position[g[s]][x](i,{targetWidth:h,targetHeight:k,elemWidth:l,elemHeight:m,collisionPosition:r,collisionWidth:v,collisionHeight:w,offset:e,my:b.my,at:b.at})});c.fn.bgiframe&&f.bgiframe();f.offset(c.extend(i,{using:b.using}))})};c.ui.position={fit:{left:function(b,a){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();b.left= 15422d>0?b.left-d:Math.max(b.left-a.collisionPosition.left,b.left)},top:function(b,a){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();b.top=d>0?b.top-d:Math.max(b.top-a.collisionPosition.top,b.top)}},flip:{left:function(b,a){if(a.at[0]!=="center"){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();var g=a.my[0]==="left"?-a.elemWidth:a.my[0]==="right"?a.elemWidth:0,e=a.at[0]==="left"?a.targetWidth:-a.targetWidth,h=-2*a.offset[0];b.left+= 15423a.collisionPosition.left<0?g+e+h:d>0?g+e+h:0}},top:function(b,a){if(a.at[1]!=="center"){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();var g=a.my[1]==="top"?-a.elemHeight:a.my[1]==="bottom"?a.elemHeight:0,e=a.at[1]==="top"?a.targetHeight:-a.targetHeight,h=-2*a.offset[1];b.top+=a.collisionPosition.top<0?g+e+h:d>0?g+e+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(b,a){if(/static/.test(c.curCSS(b,"position")))b.style.position="relative";var d=c(b), 15424g=d.offset(),e=parseInt(c.curCSS(b,"top",true),10)||0,h=parseInt(c.curCSS(b,"left",true),10)||0;g={top:a.top-g.top+e,left:a.left-g.left+h};"using"in a?a.using.call(b,g):d.css(g)};c.fn.offset=function(b){var a=this[0];if(!a||!a.ownerDocument)return null;if(b)return this.each(function(){c.offset.setOffset(this,b)});return u.call(this)}}})(jQuery); 15425;/* 15426 * jQuery UI Draggable 1.8.14 15427 * 15428 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 15429 * Dual licensed under the MIT or GPL Version 2 licenses. 15430 * http://jquery.org/license 15431 * 15432 * http://docs.jquery.com/UI/Draggables 15433 * 15434 * Depends: 15435 * jquery.ui.core.js 15436 * jquery.ui.mouse.js 15437 * jquery.ui.widget.js 15438 */ 15439(function(d){d.widget("ui.draggable",d.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:true,appendTo:"parent",axis:false,connectToSortable:false,containment:false,curs
15439or:"auto",cursorAt:false,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false},_create:function(){if(this.options.helper== 15440"original"&&!/^(?:r|a|f)/.test(this.element.css("position")))this.element[0].style.position="relative";this.options.addClasses&&this.element.addClass("ui-draggable");this.options.disabled&&this.element.addClass("ui-draggable-disabled");this._mouseInit()},destroy:function(){if(this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy();return this}},_mouseCapture:function(a){var b= 15441this.options;if(this.helper||b.disabled||d(a.target).is(".ui-resizable-handle"))return false;this.handle=this._getHandle(a);if(!this.handle)return false;d(b.iframeFix===true?"iframe":b.iframeFix).each(function(){d('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1E3}).css(d(this).offset()).appendTo("body")});return true},_mouseStart:function(a){var b=this.options;this.helper= 15442this._createHelper(a);this._cacheHelperProportions();if(d.ui.ddmanager)d.ui.ddmanager.current=this;this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}); 15443this.originalPosition=this.position=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);b.containment&&this._setContainment();if(this._trigger("start",a)===false){this._clear();return false}this._cacheHelperProportions();d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.helper.addClass("ui-draggable-dragging");this._mouseDrag(a,true);d.ui.ddmanager&&d.ui.ddmanager.dragStart(this,a);return true}, 15444_mouseDrag:function(a,b){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!b){b=this._uiHash();if(this._trigger("drag",a,b)===false){this._mouseUp({});return false}this.position=b.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);return false},_mouseStop:function(a){var b= 15445false;if(d.ui.ddmanager&&!this.options.dropBehaviour)b=d.ui.ddmanager.drop(this,a);if(this.dropped){b=this.dropped;this.dropped=false}if((!this.element[0]||!this.element[0].parentNode)&&this.options.helper=="original")return false;if(this.options.revert=="invalid"&&!b||this.options.revert=="valid"&&b||this.options.revert===true||d.isFunction(this.options.revert)&&this.options.revert.call(this.element,b)){var c=this;d(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration, 1544610),function(){c._trigger("stop",a)!==false&&c._clear()})}else this._trigger("stop",a)!==false&&this._clear();return false},_mouseUp:function(a){this.options.iframeFix===true&&d("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)});d.ui.ddmanager&&d.ui.ddmanager.dragStop(this,a);return d.ui.mouse.prototype._mouseUp.call(this,a)},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(a){var b=!this.options.handle|| 15447!d(this.options.handle,this.element).length?true:false;d(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==a.target)b=true});return b},_createHelper:function(a){var b=this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a])):b.helper=="clone"?this.element.clone().removeAttr("id"):this.element;a.parents("body").length||a.appendTo(b.appendTo=="parent"?this.element[0].parentNode:b.appendTo);a[0]!=this.element[0]&&!/(fixed|absolute)/.test(a.css("position"))&& 15448a.css("position","absolute");return a}
15448,_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top=this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent= 15449this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&false)a={top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"), 1545010)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"), 1545110)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(false),height:this.helper.outerHeight(false)}},_setContainment:function(){var a=this.options;if(a.containment=="parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[a.containment=="document"?0:d(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,a.containment=="document"?0:d(window).scrollTop()-this.offset.relative.top-this.offset.parent.top, 15452(a.containment=="document"?0:d(window).scrollLeft())+d(a.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a.containment=="document"?0:d(window).scrollTop())+(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)&&a.containment.constructor!=Array){a=d(a.containment);var b=a[0];if(b){a.offset();var c=d(b).css("overflow")!= 15453"hidden";this.containment=[(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0),(parseInt(d(b).css("borderTopWidth"),10)||0)+(parseInt(d(b).css("paddingTop"),10)||0),(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"), 1545410)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom];this.relative_container=a}}else if(a.containment.constructor==Array)this.containment=a.containment},_convertPositionTo:function(a,b){if(!b)b=this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName);return{top:b.top+ 15455this.offset.relative.top*a+this.offset.parent.top*a-(false&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(false&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():f?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&& 15456!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName),e=a.pageX,h=a.pageY;if(this.originalPosition){var g;if(this.containment){if(this.relative_container){g=this.relative_container.offset();g=[this.containment[0]+g.left,this.containment[1]+g.top,this.containment[2]+g.left,this.containment[3]+g.top]}else g=this.containment;if(a.pageX-this.offset.click.left<g[0])e=g[0]+this.offset.click.left; 15457if(a.pageY-this.offset.click.top<g[1])h=g[1]+this.offset.click.top;if(a.pageX-this.offset.click.left>g[2])e=g[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>g[3])h=g[3]+this.offset.click.top}if(b.grid){h=b.grid[1]?this.originalPageY+Math.round((h-this.originalPageY)/b.grid[1])*b.grid[1]:this.originalPageY;h=g?!(h-this.offset.click.top<g[1]||h-this.offset.click.top>g[3])?h:!(h-this.offset.click.top<g[1])?h-b.grid[1]:h+b.grid[1]:h;e=b.grid[0]?this.originalPageX+Math.round((e-this.originalPageX)
15457/ 15458b.grid[0])*b.grid[0]:this.originalPageX;e=g?!(e-this.offset.click.left<g[0]||e-this.offset.click.left>g[2])?e:!(e-this.offset.click.left<g[0])?e-b.grid[0]:e+b.grid[0]:e}}return{top:h-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(false&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop()),left:e-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(false&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():f?0:c.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging");this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove();this.helper=null;this.cancelHelperRemoval=false},_trigger:function(a,b,c){c=c||this._uiHash();d.ui.plugin.call(this,a,[b,c]);if(a=="drag")this.positionAbs=this._convertPositionTo("absolute");return d.Widget.prototype._trigger.call(this,a,b, 15459c)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}});d.extend(d.ui.draggable,{version:"1.8.14"});d.ui.plugin.add("draggable","connectToSortable",{start:function(a,b){var c=d(this).data("draggable"),f=c.options,e=d.extend({},b,{item:c.element});c.sortables=[];d(f.connectToSortable).each(function(){var h=d.data(this,"sortable");if(h&&!h.options.disabled){c.sortables.push({instance:h,shouldRevert:h.options.revert}); 15460h.refreshPositions();h._trigger("activate",a,e)}})},stop:function(a,b){var c=d(this).data("draggable"),f=d.extend({},b,{item:c.element});d.each(c.sortables,function(){if(this.instance.isOver){this.instance.isOver=0;c.cancelHelperRemoval=true;this.instance.cancelHelperRemoval=false;if(this.shouldRevert)this.instance.options.revert=true;this.instance._mouseStop(a);this.instance.options.helper=this.instance.options._helper;c.options.helper=="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})}else{this.instance.cancelHelperRemoval= 15461false;this.instance._trigger("deactivate",a,f)}})},drag:function(a,b){var c=d(this).data("draggable"),f=this;d.each(c.sortables,function(){this.instance.positionAbs=c.positionAbs;this.instance.helperProportions=c.helperProportions;this.instance.offset.click=c.offset.click;if(this.instance._intersectsWith(this.instance.containerCache)){if(!this.instance.isOver){this.instance.isOver=1;this.instance.currentItem=d(f).clone().removeAttr("id").appendTo(this.instance.element).data("sortable-item",true); 15462this.instance.options._helper=this.instance.options.helper;this.instance.options.helper=function(){return b.helper[0]};a.target=this.instance.currentItem[0];this.instance._mouseCapture(a,true);this.instance._mouseStart(a,true,true);this.instance.offset.click.top=c.offset.click.top;this.instance.offset.click.left=c.offset.click.left;this.instance.offset.parent.left-=c.offset.parent.left-this.instance.offset.parent.left;this.instance.offset.parent.top-=c.offset.parent.top-this.instance.offset.parent.top; 15463c._trigger("toSortable",a);c.dropped=this.instance.element;c.currentItem=c.element;this.instance.fromOutside=c}this.instance.currentItem&&this.instance._mouseDrag(a)}else if(this.instance.isOver){this.instance.isOver=0;this.instance.cancelHelperRemoval=true;this.instance.options.revert=false;this.instance._trigger("out",a,this.instance._uiHash(this.instance));this.instance._mouseStop(a,true);this.instance.options.helper=this.instance.options._helper;this.instance.currentItem.remove();this.instance.placeholder&& 15464this.instance.placeholder.remove();c._trigger("fromSortable",a);c.dropped=false}})}});d.ui.plugin.add("draggable","cursor",{start:function(){var a=d("body"),b=d(this).data("draggable").options;if(a.css("cursor"))b._cursor=a.css("cursor");a.css("cursor",b.cursor)},stop:function(){var a=d(this).data("draggable").options;a._cursor&&d("body").css("cursor",a._cursor)}});d.ui.plugin.add("draggable","opacity",{start:function(a,b){a=d(b.helper);b=d(this).data("draggable").options;if(a.css("opacity"))b._opacity= 15465a.css("opacity");a.css("opacity",b.opacity)},stop:function(a,b){a=d(this).data("draggable").options;a._opacity&&d(b.helper).css("opacity",a._opacity)}});d.ui.plugin.add("draggable","scroll",{start:function(){var a=d(this).data("draggable");if(a.scrollParent[0]!=document&&a.scrollParent[0].tagName!="HTML")a.overflowOffset=a.scrollParent.offset()},drag:function(a){var b=d(this).data("draggable"),c=b.options,f=false;if(b.scrollParent[0]!=document&&b.scrollParent[0].tagName!="HTML"){if(!c.axis||c.axis!= 15466"x")if(b.overflowOffset.top+b.scrollParent[0].offsetHeight-a.pageY<c.scrollSensitivity)b.scrollParent[0].scrollTop=f=b.scrollParent[0].scrollTop+c.scrollSpeed;else if(a.pageY-b.overflowOffset.top<c.scrollSensitivity)b.scrollParent[0].scrollTop=f=b.scrollParent[0].scrollTop-c.scrollSpeed;if(!c.axis||c.axis!="y")if(b.overflowOffset.left+b.scrollParent[0].offsetWidth-a.pageX<c.scrollSensitivity)b.scrollParent[0].scrollLeft=f=b.scrollParent[0].scrollLeft+c.scrollSpeed;else if(a.pageX-b.overflowOffset.left< 15467c.scrollSensitivity)b.scrollParent[0].scrollLeft=f=b.scrollParent[0].scrollLeft-c.scrollSpeed}else{if(!c.axis||c.axis!="x")if(a.pageY-d(document).scrollTop()<c.scrollSensitivity)f=d(document).scrollTop(d(document).scrollTop()-c.scrollSpeed);else if(d(window).height()-(a.pageY-d(document).scrollTop())<c.scrollSensitivity)f=d(document).scrollTop(d(document).scrollTop()+c.scrollSpeed);if(!c.axis||c.axis!="y")if(a.pageX-d(document).scrollLeft()<c.scrollSensitivity)f=d(document).scrollLeft(d(document).scrollLeft()- 15468c.scrollSpeed);else if(d(window).width()-(a.pageX-d(document).scrollLeft())<c.scrollSensitivity)f=d(document).scrollLeft(d(document).scrollLeft()+c.scrollSpeed)}f!==false&&d.ui.ddmanager&&!c.dropBehaviour&&d.ui.ddmanager.prepareOffsets(b,a)}});d.ui.plugin.add("draggable","snap",{start:function(){var a=d(this).data("draggable"),b=a.options;a.snapElements=[];d(b.snap.constructor!=String?b.snap.items||":data(draggable)":b.snap).each(function(){var c=d(this),f=c.offset();this!=a.element[0]&&a.snapElements.push({item:this, 15469width:c.outerWidth(false),height:c.outerHeight(false),top:f.top,left
15469:f.left})})},drag:function(a,b){for(var c=d(this).data("draggable"),f=c.options,e=f.snapTolerance,h=b.offset.left,g=h+c.helperProportions.width,n=b.offset.top,o=n+c.helperProportions.height,i=c.snapElements.length-1;i>=0;i--){var j=c.snapElements[i].left,l=j+c.snapElements[i].width,k=c.snapElements[i].top,m=k+c.snapElements[i].height;if(j-e<h&&h<l+e&&k-e<n&&n<m+e||j-e<h&&h<l+e&&k-e<o&&o<m+e||j-e<g&&g<l+e&&k-e<n&&n<m+e||j-e<g&&g<l+e&&k-e<o&& 15470o<m+e){if(f.snapMode!="inner"){var p=Math.abs(k-o)<=e,q=Math.abs(m-n)<=e,r=Math.abs(j-g)<=e,s=Math.abs(l-h)<=e;if(p)b.position.top=c._convertPositionTo("relative",{top:k-c.helperProportions.height,left:0}).top-c.margins.top;if(q)b.position.top=c._convertPositionTo("relative",{top:m,left:0}).top-c.margins.top;if(r)b.position.left=c._convertPositionTo("relative",{top:0,left:j-c.helperProportions.width}).left-c.margins.left;if(s)b.position.left=c._convertPositionTo("relative",{top:0,left:l}).left-c.margins.left}var t= 15471p||q||r||s;if(f.snapMode!="outer"){p=Math.abs(k-n)<=e;q=Math.abs(m-o)<=e;r=Math.abs(j-h)<=e;s=Math.abs(l-g)<=e;if(p)b.position.top=c._convertPositionTo("relative",{top:k,left:0}).top-c.margins.top;if(q)b.position.top=c._convertPositionTo("relative",{top:m-c.helperProportions.height,left:0}).top-c.margins.top;if(r)b.position.left=c._convertPositionTo("relative",{top:0,left:j}).left-c.margins.left;if(s)b.position.left=c._convertPositionTo("relative",{top:0,left:l-c.helperProportions.width}).left-c.margins.left}if(!c.snapElements[i].snapping&& 15472(p||q||r||s||t))c.options.snap.snap&&c.options.snap.snap.call(c.element,a,d.extend(c._uiHash(),{snapItem:c.snapElements[i].item}));c.snapElements[i].snapping=p||q||r||s||t}else{c.snapElements[i].snapping&&c.options.snap.release&&c.options.snap.release.call(c.element,a,d.extend(c._uiHash(),{snapItem:c.snapElements[i].item}));c.snapElements[i].snapping=false}}}});d.ui.plugin.add("draggable","stack",{start:function(){var a=d(this).data("draggable").options;a=d.makeArray(d(a.stack)).sort(function(c,f){return(parseInt(d(c).css("zIndex"), 1547310)||0)-(parseInt(d(f).css("zIndex"),10)||0)});if(a.length){var b=parseInt(a[0].style.zIndex)||0;d(a).each(function(c){this.style.zIndex=b+c});this[0].style.zIndex=b+a.length}}});d.ui.plugin.add("draggable","zIndex",{start:function(a,b){a=d(b.helper);b=d(this).data("draggable").options;if(a.css("zIndex"))b._zIndex=a.css("zIndex");a.css("zIndex",b.zIndex)},stop:function(a,b){a=d(this).data("draggable").options;a._zIndex&&d(b.helper).css("zIndex",a._zIndex)}})})(jQuery); 15474;/* 15475 * jQuery UI Droppable 1.8.14 15476 * 15477 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 15478 * Dual licensed under the MIT or GPL Version 2 licenses. 15479 * http://jquery.org/license 15480 * 15481 * http://docs.jquery.com/UI/Droppables 15482 * 15483 * Depends: 15484 * jquery.ui.core.js 15485 * jquery.ui.widget.js 15486 * jquery.ui.mouse.js 15487 * jquery.ui.draggable.js 15488 */ 15489(function(d){d.widget("ui.droppable",{widgetEventPrefix:"drop",options:{accept:"*",activeClass:false,addClasses:true,greedy:false,hoverClass:false,scope:"default",tolerance:"intersect"},_create:function(){var a=this.options,b=a.accept;this.isover=0;this.isout=1;this.accept=d.isFunction(b)?b:function(c){return c.is(b)};this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight};d.ui.ddmanager.droppables[a.scope]=d.ui.ddmanager.droppables[a.scope]||[];d.ui.ddmanager.droppables[a.scope].push(this); 15490a.addClasses&&this.element.addClass("ui-droppable")},destroy:function(){for(var a=d.ui.ddmanager.droppables[this.options.scope],b=0;b<a.length;b++)a[b]==this&&a.splice(b,1);this.element.removeClass("ui-droppable ui-droppable-disabled").removeData("droppable").unbind(".droppable");return this},_setOption:function(a,b){if(a=="accept")this.accept=d.isFunction(b)?b:function(c){return c.is(b)};d.Widget.prototype._setOption.apply(this,arguments)},_activate:function(a){var b=d.ui.ddmanager.current;this.options.activeClass&& 15491this.element.addClass(this.options.activeClass);b&&this._trigger("activate",a,this.ui(b))},_deactivate:function(a){var b=d.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass);b&&this._trigger("deactivate",a,this.ui(b))},_over:function(a){var b=d.ui.ddmanager.current;if(!(!b||(b.currentItem||b.element)[0]==this.element[0]))if(this.accept.call(this.element[0],b.currentItem||b.element)){this.options.hoverClass&&this.element.addClass(this.options.hoverClass); 15492this._trigger("over",a,this.ui(b))}},_out:function(a){var b=d.ui.ddmanager.current;if(!(!b||(b.currentItem||b.element)[0]==this.element[0]))if(this.accept.call(this.element[0],b.currentItem||b.element)){this.options.hoverClass&&this.element.removeClass(this.options.hoverClass);this._trigger("out",a,this.ui(b))}},_drop:function(a,b){var c=b||d.ui.ddmanager.current;if(!c||(c.currentItem||c.element)[0]==this.element[0])return false;var e=false;this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var g= 15493d.data(this,"droppable");if(g.options.greedy&&!g.options.disabled&&g.options.scope==c.options.scope&&g.accept.call(g.element[0],c.currentItem||c.element)&&d.ui.intersect(c,d.extend(g,{offset:g.element.offset()}),g.options.tolerance)){e=true;return false}});if(e)return false;if(this.accept.call(this.element[0],c.currentItem||c.element)){this.options.activeClass&&this.element.removeClass(this.options.activeClass);this.options.hoverClass&&this.element.removeClass(this.options.hoverClass);this._trigger("drop", 15494a,this.ui(c));return this.element}return false},ui:function(a){return{draggable:a.currentItem||a.element,helper:
15494a.helper,position:a.position,offset:a.positionAbs}}});d.extend(d.ui.droppable,{version:"1.8.14"});d.ui.intersect=function(a,b,c){if(!b.offset)return false;var e=(a.positionAbs||a.position.absolute).left,g=e+a.helperProportions.width,f=(a.positionAbs||a.position.absolute).top,h=f+a.helperProportions.height,i=b.offset.left,k=i+b.proportions.width,j=b.offset.top,l=j+b.proportions.height; 15495switch(c){case "fit":return i<=e&&g<=k&&j<=f&&h<=l;case "intersect":return i<e+a.helperProportions.width/2&&g-a.helperProportions.width/2<k&&j<f+a.helperProportions.height/2&&h-a.helperProportions.height/2<l;case "pointer":return d.ui.isOver((a.positionAbs||a.position.absolute).top+(a.clickOffset||a.offset.click).top,(a.positionAbs||a.position.absolute).left+(a.clickOffset||a.offset.click).left,j,i,b.proportions.height,b.proportions.width);case "touch":return(f>=j&&f<=l||h>=j&&h<=l||f<j&&h>l)&&(e>= 15496i&&e<=k||g>=i&&g<=k||e<i&&g>k);default:return false}};d.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(a,b){var c=d.ui.ddmanager.droppables[a.options.scope]||[],e=b?b.type:null,g=(a.currentItem||a.element).find(":data(droppable)").andSelf(),f=0;a:for(;f<c.length;f++)if(!(c[f].options.disabled||a&&!c[f].accept.call(c[f].element[0],a.currentItem||a.element))){for(var h=0;h<g.length;h++)if(g[h]==c[f].element[0]){c[f].proportions.height=0;continue a}c[f].visible=c[f].element.css("display")!= 15497"none";if(c[f].visible){e=="mousedown"&&c[f]._activate.call(c[f],b);c[f].offset=c[f].element.offset();c[f].proportions={width:c[f].element[0].offsetWidth,height:c[f].element[0].offsetHeight}}}},drop:function(a,b){var c=false;d.each(d.ui.ddmanager.droppables[a.options.scope]||[],function(){if(this.options){if(!this.options.disabled&&this.visible&&d.ui.intersect(a,this,this.options.tolerance))c=c||this._drop.call(this,b);if(!this.options.disabled&&this.visible&&this.accept.call(this.element[0],a.currentItem|| 15498a.element)){this.isout=1;this.isover=0;this._deactivate.call(this,b)}}});return c},dragStart:function(a,b){a.element.parentsUntil("body").bind("scroll.droppable",function(){a.options.refreshPositions||d.ui.ddmanager.prepareOffsets(a,b)})},drag:function(a,b){a.options.refreshPositions&&d.ui.ddmanager.prepareOffsets(a,b);d.each(d.ui.ddmanager.droppables[a.options.scope]||[],function(){if(!(this.options.disabled||this.greedyChild||!this.visible)){var c=d.ui.intersect(a,this,this.options.tolerance);if(c= 15499!c&&this.isover==1?"isout":c&&this.isover==0?"isover":null){var e;if(this.options.greedy){var g=this.element.parents(":data(droppable):eq(0)");if(g.length){e=d.data(g[0],"droppable");e.greedyChild=c=="isover"?1:0}}if(e&&c=="isover"){e.isover=0;e.isout=1;e._out.call(e,b)}this[c]=1;this[c=="isout"?"isover":"isout"]=0;this[c=="isover"?"_over":"_out"].call(this,b);if(e&&c=="isout"){e.isout=0;e.isover=1;e._over.call(e,b)}}}})},dragStop:function(a,b){a.element.parentsUntil("body").unbind("scroll.droppable"); 15500a.options.refreshPositions||d.ui.ddmanager.prepareOffsets(a,b)}}})(jQuery); 15501;/* 15502 * jQuery UI Resizable 1.8.14 15503 * 15504 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 15505 * Dual licensed under the MIT or GPL Version 2 licenses. 15506 * http://jquery.org/license 15507 * 15508 * http://docs.jquery.com/UI/Resizables 15509 * 15510 * Depends: 15511 * jquery.ui.core.js 15512 * jquery.ui.mouse.js 15513 * jquery.ui.widget.js 15514 */ 15515(function(e){e.widget("ui.resizable",e.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1E3},_create:function(){var b=this,a=this.options;this.element.addClass("ui-resizable");e.extend(this,{_aspectRatio:!!a.aspectRatio,aspectRatio:a.aspectRatio,originalElement:this.element, 15516_proportionallyResizeElements:[],_helper:a.helper||a.ghost||a.animate?a.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){/relative/.test(this.element.css("position"))&&false&&this.element.css({position:"relative",top:"auto",left:"auto"});
15516this.element.wrap(e('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(false),height:this.element.outerHeight(false), 15517top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle= 15518this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=a.handles||(!e(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne", 15519nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all")this.handles="n,e,s,w,se,sw,ne,nw";var c=this.handles.split(",");this.handles={};for(var d=0;d<c.length;d++){var f=e.trim(c[d]),g=e('<div class="ui-resizable-handle '+("ui-resizable-"+f)+'"></div>');/sw|se|ne|nw/.test(f)&&g.css({zIndex:++a.zIndex});"se"==f&&g.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[f]=".ui-resizable-"+f;this.element.append(g)}}this._renderAxis=function(h){h=h||this.element;for(var i in this.handles){if(this.handles[i].constructor== 15520String)this.handles[i]=e(this.handles[i],this.element).show();if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var j=e(this.handles[i],this.element),l=0;l=/sw|ne|nw|se|n|s/.test(i)?j.outerHeight(false):j.outerWidth(false);j=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join("");h.css(j,l);this._proportionallyResize()}e(this.handles[i])}};this._renderAxis(this.element);this._handles=e(".ui-resizable-handle",this.element).disableSelection(); 15521this._handles.mouseover(function(){if(!b.resizing){if(this.className)var h=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=h&&h[1]?h[1]:"se"}});if(a.autoHide){this._handles.hide();e(this.element).addClass("ui-resizable-autohide").hover(function(){if(!a.disabled){e(this).removeClass("ui-resizable-autohide");b._handles.show()}},function(){if(!a.disabled)if(!b.resizing){e(this).addClass("ui-resizable-autohide");b._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy(); 15522var b=function(c){e(c).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){b(this.element);var a=this.element;a.after(this.originalElement.css({position:a.css("position"),width:a.outerWidth(false),height:a.outerHeight(false),top:a.css("top"),left:a.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);b(this.originalElement);return this},_mouseCapture:function(b){var a= 15523false;for(var c in this.handles)if(e(this.handles[c])[0]==b.target)a=true;return!this.options.disabled&&a},_mouseStart:function(b){var a=this.options,c=this.element.position(),d=this.element;this.resizing=true;this.documentScroll={top:e(document).scrollTop(),left:e(document).scrollLeft()};if(d.is(".ui-draggable")||/absolute/.test(d.css("position")))d.css({position:"absolute",top:c.top,left:c.left});false&&/relative/.test(d.css("position"))&&d.css({position:"relative",top:"auto",left:"auto"}); 15524this._renderProxy();c=m(this.helper.css("left"));var f=m(this.helper.css("top"));if(a.containment){c+=e(a.containment).scrollLeft()||0;f+=e(a.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:c,top:f};this.size=this._helper?{width:d.outerWidth(false),height:d.outerHeight(false)}:{width:d.width(),height:d.height()};this.originalSize=this._helper?{width:d.outerWidth(false),height:d.outerHeight(false)}:{width:d.width(),height:d.height()};this.originalPosition={left:c,top:f};this.sizeDiff= 15525{width:d.outerWidth(false)-d.width(),height:d.outerHeight(false)-d.height()};this.originalMousePosition={left:b.pageX,top:b.pageY};this.aspectRatio=typeof a.aspectRatio=="number"?a.aspectRatio:this.originalSize.width/this.originalSize.height||1;a=e(".ui-resizable-"+this.axis).css("cursor");e("body").css("cursor",a=="auto"?this.axis+"-resize":a);d.addClass("ui-resizable-resizing");this._propagate("start",b);return true},_mouseDrag:function(b){var a=this.helper,c=this.originalMousePosition,d=this._change[this.axis]; 15526if(!d)return false;c=d.apply(this,[b,b.pageX-c.left||0,b.pageY-c.top||0]);this._updateVirtualBoundaries(b.shiftKey);if(this._aspectRatio||b.shiftKey)c=this._updateRatio(c,b);c=this._respectSize(c,b);this._propagate("resize",b);a.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(c);this._trigger("resize",b,this.ui());return false}, 15527_mouseStop:function(b){this.resizing=false;var a=this.options,c=this;if(this._helper){var d=this._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName);d=f&&e.ui.hasScroll(d[0],"left")?0:c.sizeDiff.height;f=f?0:c.sizeDiff.width;f={width:c.helper.width()-f,height:c.helper.height()-d};d=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null;var g=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null;a.animate||this.element.css(e.extend(f, 15528{top:g,left:d}));c.helper.height(c.size.height);c.helper.width(c.size.width);this._helper&&!a.animate&&this._proportionallyResize()}e("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",b);this._helper&&this.helper.remove();return false},_updateVirtualBoundaries:function(b){var a=this.options,c,d,f;a={minWidth:k(a.minWidth)?a.minWidth:0,maxWidth:k(a.maxWidth)?a.maxWidth:Infinity,minHeight:k(a.minHeight)?a.minHeight:0,maxHeight:k(a.maxHeight)?a.maxHeight: 15529Infinity};if(this._aspectRatio||b){b=a.minHeight*this.aspectRatio;d=a.minWidth/this.aspectRatio;c=a.maxHeight*this.aspectRatio;f=a.maxWidth/this.aspectRatio;if(b>a.minWidth)a.minWidth=b;if(d>a.minHeight)a.minHeight=d;if(c<a.maxWidth)a.maxWidth=c;if(f<a.maxHeight)a.maxHeight=f}this._vBoundaries=a},_updateCache:function(b){this.offset=this.helper.offset();
15529if(k(b.left))this.position.left=b.left;if(k(b.top))this.position.top=b.top;if(k(b.height))this.size.height=b.height;if(k(b.width))this.size.width= 15530b.width},_updateRatio:function(b){var a=this.position,c=this.size,d=this.axis;if(k(b.height))b.width=b.height*this.aspectRatio;else if(k(b.width))b.height=b.width/this.aspectRatio;if(d=="sw"){b.left=a.left+(c.width-b.width);b.top=null}if(d=="nw"){b.top=a.top+(c.height-b.height);b.left=a.left+(c.width-b.width)}return b},_respectSize:function(b){var a=this._vBoundaries,c=this.axis,d=k(b.width)&&a.maxWidth&&a.maxWidth<b.width,f=k(b.height)&&a.maxHeight&&a.maxHeight<b.height,g=k(b.width)&&a.minWidth&& 15531a.minWidth>b.width,h=k(b.height)&&a.minHeight&&a.minHeight>b.height;if(g)b.width=a.minWidth;if(h)b.height=a.minHeight;if(d)b.width=a.maxWidth;if(f)b.height=a.maxHeight;var i=this.originalPosition.left+this.originalSize.width,j=this.position.top+this.size.height,l=/sw|nw|w/.test(c);c=/nw|ne|n/.test(c);if(g&&l)b.left=i-a.minWidth;if(d&&l)b.left=i-a.maxWidth;if(h&&c)b.top=j-a.minHeight;if(f&&c)b.top=j-a.maxHeight;if((a=!b.width&&!b.height)&&!b.left&&b.top)b.top=null;else if(a&&!b.top&&b.left)b.left= 15532null;return b},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var b=this.helper||this.element,a=0;a<this._proportionallyResizeElements.length;a++){var c=this._proportionallyResizeElements[a];if(!this.borderDif){var d=[c.css("borderTopWidth"),c.css("borderRightWidth"),c.css("borderBottomWidth"),c.css("borderLeftWidth")],f=[c.css("paddingTop"),c.css("paddingRight"),c.css("paddingBottom"),c.css("paddingLeft")];this.borderDif=e.map(d,function(g,h){g=parseInt(g,10)|| 155330;h=parseInt(f[h],10)||0;return g+h})}false&&(e(b).is(":hidden")||e(b).parents(":hidden").length)||c.css({height:b.height()-this.borderDif[0]-this.borderDif[2]||0,width:b.width()-this.borderDif[1]-this.borderDif[3]||0})}},_renderProxy:function(){var b=this.options;this.elementOffset=this.element.offset();if(this._helper){this.helper=this.helper||e('<div style="overflow:hidden;"></div>');var a=false,c=a?1:0;a=a?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth(false)+ 15534a,height:this.element.outerHeight(false)+a,position:"absolute",left:this.elementOffset.left-c+"px",top:this.elementOffset.top-c+"px",zIndex:++b.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(b,a){return{width:this.originalSize.width+a}},w:function(b,a){return{left:this.originalPosition.left+a,width:this.originalSize.width-a}},n:function(b,a,c){return{top:this.originalPosition.top+c,height:this.originalSize.height-c}},s:function(b,a,c){return{height:this.originalSize.height+ 15535c}},se:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},sw:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,a,c]))},ne:function(b,a,c){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},nw:function(b,a,c){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,a,c]))}},_propagate:function(b,a){e.ui.plugin.call(this,b,[a,this.ui()]); 15536b!="resize"&&this._trigger(b,a,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});e.extend(e.ui.resizable,{version:"1.8.14"});e.ui.plugin.add("resizable","alsoResize",{start:function(){var b=e(this).data("resizable").options,a=function(c){e(c).each(function(){var d=e(this);d.data("resizable-alsoresize",{width:parseInt(d.width(), 1553710),height:parseInt(d.height(),10),left:parseInt(d.css("left"),10),top:parseInt(d.css("top"),10),position:d.css("position")})})};if(typeof b.alsoResize=="object"&&!b.alsoResize.parentNode)if(b.alsoResize.length){b.alsoResize=b.alsoResize[0];a(b.alsoResize)}else e.each(b.alsoResize,function(c){a(c)});else a(b.alsoResize)},resize:function(b,a){var c=e(this).data("resizable");b=c.options;
15537var d=c.originalSize,f=c.originalPosition,g={height:c.size.height-d.height||0,width:c.size.width-d.width||0,top:c.position.top- 15538f.top||0,left:c.position.left-f.left||0},h=function(i,j){e(i).each(function(){var l=e(this),q=e(this).data("resizable-alsoresize"),p={},r=j&&j.length?j:l.parents(a.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(r,function(n,o){if((n=(q[o]||0)+(g[o]||0))&&n>=0)p[o]=n||null});if(false&&/relative/.test(l.css("position"))){c._revertToRelativePosition=true;l.css({position:"absolute",top:"auto",left:"auto"})}l.css(p)})};typeof b.alsoResize=="object"&&!b.alsoResize.nodeType? 15539e.each(b.alsoResize,function(i,j){h(i,j)}):h(b.alsoResize)},stop:function(){var b=e(this).data("resizable"),a=b.options,c=function(d){e(d).each(function(){var f=e(this);f.css({position:f.data("resizable-alsoresize").position})})};if(b._revertToRelativePosition){b._revertToRelativePosition=false;typeof a.alsoResize=="object"&&!a.alsoResize.nodeType?e.each(a.alsoResize,function(d){c(d)}):c(a.alsoResize)}e(this).removeData("resizable-alsoresize")}});e.ui.plugin.add("resizable","animate",{stop:function(b){var a= 15540e(this).data("resizable"),c=a.options,d=a._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName),g=f&&e.ui.hasScroll(d[0],"left")?0:a.sizeDiff.height;f={width:a.size.width-(f?0:a.sizeDiff.width),height:a.size.height-g};g=parseInt(a.element.css("left"),10)+(a.position.left-a.originalPosition.left)||null;var h=parseInt(a.element.css("top"),10)+(a.position.top-a.originalPosition.top)||null;a.element.animate(e.extend(f,h&&g?{top:h,left:g}:{}),{duration:c.animateDuration,easing:c.animateEasing, 15541step:function(){var i={width:parseInt(a.element.css("width"),10),height:parseInt(a.element.css("height"),10),top:parseInt(a.element.css("top"),10),left:parseInt(a.element.css("left"),10)};d&&d.length&&e(d[0]).css({width:i.width,height:i.height});a._updateCache(i);a._propagate("resize",b)}})}});e.ui.plugin.add("resizable","containment",{start:function(){var b=e(this).data("resizable"),a=b.element,c=b.options.containment;if(a=c instanceof e?c.get(0):/parent/.test(c)?a.parent().get(0):c){b.containerElement= 15542e(a);if(/document/.test(c)||c==document){b.containerOffset={left:0,top:0};b.containerPosition={left:0,top:0};b.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}}else{var d=e(a),f=[];e(["Top","Right","Left","Bottom"]).each(function(i,j){f[i]=m(d.css("padding"+j))});b.containerOffset=d.offset();b.containerPosition=d.position();b.containerSize={height:d.innerHeight()-f[3],width:d.innerWidth()-f[1]};c=b.containerOffset; 15543var g=b.containerSize.height,h=b.containerSize.width;h=e.ui.hasScroll(a,"left")?a.scrollWidth:h;g=e.ui.hasScroll(a)?a.scrollHeight:g;b.parentData={element:a,left:c.left,top:c.top,width:h,height:g}}}},resize:function(b){var a=e(this).data("resizable"),c=a.options,d=a.containerOffset,f=a.position;b=a._aspectRatio||b.shiftKey;var g={top:0,left:0},h=a.containerElement;if(h[0]!=document&&/static/.test(h.css("position")))g=d;if(f.left<(a._helper?d.left:0)){a.size.width+=a._helper?a.position.left-d.left: 15544a.position.left-g.left;if(b)a.size.height=a.size.width/c.aspectRatio;a.position.left=c.helper?d.left:0}if(f.top<(a._helper?d.top:0)){a.size.height+=a._helper?a.position.top-d.top:a.position.top;if(b)a.size.width=a.size.height*c.aspectRatio;a.position.top=a._helper?d.top:0}a.offset.left=a.parentData.left+a.position.left;a.offset.top=a.parentData.top+a.position.top;c=Math.abs((a._helper?a.offset.left-g.left:a.offset.left-g.left)+a.sizeDiff.width);d=Math.abs((a._helper?a.offset.top-g.top:a.offset.top- 15545d.top)+a.sizeDiff.height);f=a.containerElement.get(0)==a.element.parent().get(0);g=/relative|absolute/.test(a.containerElement.css("position"));if(f&&g)c-=a.parentData.left;if(c+a.size.width>=a.parentData.width){a.size.width=a.parentData.width-c;if(b)a.size.height=a.size.width/a.aspectRatio}if(d+a.size.height>=a.parentData.height){a.size.height=a.parentData.height-d;if(b)a.size.width=a.size.height*a.aspectRatio}},stop:function(){var b=e(this).data("resizable"),a=b.options,c=b.containerOffset,d=b.containerPosition, 15546f=b.containerElement,g=e(b.helper),h=g.offset(),i=g.outerWidth(false)-b.sizeDiff.width;g=g.outerHeight(false)-b.sizeDiff.height;b._helper&&!a.animate&&/relative/.test(f.css("position"))&&e(this).css({left:h.left-d.left-c.left,width:i,height:g});b._helper&&!a.animate&&/static/.test(f.css("position"))&&e(this).css({left:h.left-d.left-c.left,width:i,height:g})}});e.ui.plugin.add("resizable","ghost",{start:function(){var b=e(this).data("resizable"),a=b.options,c=b.size;b.ghost=b.originalElement.clone();b.ghost.css({opacity:0.25, 15547display:"block",position:"relative",height:c.height,width:c.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof a.ghost=="string"?a.ghost:"");b.ghost.appendTo(b.helper)},resize:function(){var b=e(this).data("resizable");b.ghost&&b.ghost.css({position:"relative",height:b.size.height,width:b.size.width})},stop:function(){var b=e(this).data("resizable");b.ghost&&b.helper&&b.helper.get(0).removeChild(b.ghost.get(0))}});e.ui.plugin.add("resizable","grid",{resize:function(){var b= 15548e(this).data("resizable"),a=b.options,c=b.size,d=b.originalSize,f
15548=b.originalPosition,g=b.axis;a.grid=typeof a.grid=="number"?[a.grid,a.grid]:a.grid;var h=Math.round((c.width-d.width)/(a.grid[0]||1))*(a.grid[0]||1);a=Math.round((c.height-d.height)/(a.grid[1]||1))*(a.grid[1]||1);if(/^(se|s|e)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a}else if(/^(ne)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}else{if(/^(sw)$/.test(g)){b.size.width=d.width+h;b.size.height= 15549d.height+a}else{b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}b.position.left=f.left-h}}});var m=function(b){return parseInt(b,10)||0},k=function(b){return!isNaN(parseInt(b,10))}})(jQuery); 15550;/* 15551 * jQuery UI Selectable 1.8.14 15552 * 15553 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 15554 * Dual licensed under the MIT or GPL Version 2 licenses. 15555 * http://jquery.org/license 15556 * 15557 * http://docs.jquery.com/UI/Selectables 15558 * 15559 * Depends: 15560 * jquery.ui.core.js 15561 * jquery.ui.mouse.js 15562 * jquery.ui.widget.js 15563 */ 15564(function(e){e.widget("ui.selectable",e.ui.mouse,{options:{appendTo:"body",autoRefresh:true,distance:0,filter:"*",tolerance:"touch"},_create:function(){var c=this;this.element.addClass("ui-selectable");this.dragged=false;var f;this.refresh=function(){f=e(c.options.filter,c.element[0]);f.each(function(){var d=e(this),b=d.offset();e.data(this,"selectable-item",{element:this,$element:d,left:b.left,top:b.top,right:b.left+d.outerWidth(false),bottom:b.top+d.outerHeight(false),startselected:false,selected:d.hasClass("ui-selected"), 15565selecting:d.hasClass("ui-selecting"),unselecting:d.hasClass("ui-unselecting")})})};this.refresh();this.selectees=f.addClass("ui-selectee");this._mouseInit();this.helper=e("<div class='ui-selectable-helper'></div>")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item");this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy();return this},_mouseStart:function(c){var f=this;this.opos=[c.pageX, 15566c.pageY];if(!this.options.disabled){var d=this.options;this.selectees=e(d.filter,this.element[0]);this._trigger("start",c);e(d.appendTo).append(this.helper);this.helper.css({left:c.clientX,top:c.clientY,width:0,height:0});d.autoRefresh&&this.refresh();this.selectees.filter(".ui-selected").each(function(){var b=e.data(this,"selectable-item");b.startselected=true;if(!c.metaKey){b.$element.removeClass("ui-selected");b.selected=false;b.$element.addClass("ui-unselecting");b.unselecting=true;f._trigger("unselecting", 15567c,{unselecting:b.element})}});e(c.target).parents().andSelf().each(function(){var b=e.data(this,"selectable-item");if(b){var g=!c.metaKey||!b.$element.hasClass("ui-selected");b.$element.removeClass(g?"ui-unselecting":"ui-selected").addClass(g?"ui-selecting":"ui-unselecting");b.unselecting=!g;b.selecting=g;(b.selected=g)?f._trigger("selecting",c,{selecting:b.element}):f._trigger("unselecting",c,{unselecting:b.element});return false}})}},_mouseDrag:function(c){var f=this;this.dragged=true;if(!this.options.disabled){var d= 15568this.options,b=this.opos[0],g=this.opos[1],h=c.pageX,i=c.pageY;if(b>h){var j=h;h=b;b=j}if(g>i){j=i;i=g;g=j}this.helper.css({left:b,top:g,width:h-b,height:i-g});this.selectees.each(function(){var a=e.data(this,"selectable-item");if(!(!a||a.element==f.element[0])){var k=false;if(d.tolerance=="touch")k=!(a.left>h||a.right<b||a.top>i||a.bottom<g);else if(d.tolerance=="fit")k=a.left>b&&a.right<h&&a.top>g&&a.bottom<i;if(k){if(a.selected){a.$element.removeClass("ui-selected");a.selected=false}if(a.unselecting){a.$element.removeClass("ui-unselecting"); 15569a.unselecting=false}if(!a.selecting){a.$element.addClass("ui-selecting");a.selecting=true;f._trigger("selecting",c,{selecting:a.element})}}else{if(a.selecting)if(c.metaKey&&a.startselected){a.$element.removeClass("ui-selecting");a.selecting=false;a.$element.addClass("ui-selected");a.selected=true}else{a.$element.removeClass("ui-selecting");a.selecting=false;if(a.startselected){a.$element.addClass("ui-unselecting");a.unselecting=true}f._trigger("unselecting",c,{unselecting:a.element})}
15569if(a.selected)if(!c.metaKey&& 15570!a.startselected){a.$element.removeClass("ui-selected");a.selected=false;a.$element.addClass("ui-unselecting");a.unselecting=true;f._trigger("unselecting",c,{unselecting:a.element})}}}});return false}},_mouseStop:function(c){var f=this;this.dragged=false;e(".ui-unselecting",this.element[0]).each(function(){var d=e.data(this,"selectable-item");d.$element.removeClass("ui-unselecting");d.unselecting=false;d.startselected=false;f._trigger("unselected",c,{unselected:d.element})});e(".ui-selecting",this.element[0]).each(function(){var d= 15571e.data(this,"selectable-item");d.$element.removeClass("ui-selecting").addClass("ui-selected");d.selecting=false;d.selected=true;d.startselected=true;f._trigger("selected",c,{selected:d.element})});this._trigger("stop",c);this.helper.remove();return false}});e.extend(e.ui.selectable,{version:"1.8.14"})})(jQuery); 15572;/* 15573 * jQuery UI Sortable 1.8.14 15574 * 15575 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 15576 * Dual licensed under the MIT or GPL Version 2 licenses. 15577 * http://jquery.org/license 15578 * 15579 * http://docs.jquery.com/UI/Sortables 15580 * 15581 * Depends: 15582 * jquery.ui.core.js 15583 * jquery.ui.mouse.js 15584 * jquery.ui.widget.js 15585 */ 15586(function(d){d.widget("ui.sortable",d.ui.mouse,{widgetEventPrefix:"sort",options:{appendTo:"parent",axis:false,connectWith:false,containment:false,cursor:"auto",cursorAt:false,dropOnEmpty:true,forcePlaceholderSize:false,forceHelperSize:false,grid:false,handle:false,helper:"original",items:"> *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){var a=this.options;this.containerCache={};this.element.addClass("ui-sortable"); 15587this.refresh();this.floating=this.items.length?a.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var a=this.items.length-1;a>=0;a--)this.items[a].item.removeData("sortable-item");return this},_setOption:function(a,b){if(a=== 15588"disabled"){this.options[a]=b;this.widget()[b?"addClass":"removeClass"]("ui-sortable-disabled")}else d.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(a,b){if(this.reverting)return false;if(this.options.disabled||this.options.type=="static")return false;this._refreshItems(a);var c=null,e=this;d(a.target).parents().each(function(){if(d.data(this,"sortable-item")==e){c=d(this);return false}});if(d.data(a.target,"sortable-item")==e)c=d(a.target);if(!c)return false;if(this.options.handle&& 15589!b){var f=false;d(this.options.handle,c).find("*").andSelf().each(function(){if(this==a.target)f=true});if(!f)return false}this.currentItem=c;this._removeCurrentsFromItems();return true},_mouseStart:function(a,b,c){b=this.options;var e=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(a);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top, 15590left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]}; 15591this.helper[0]!=this.currentItem[0]&&this.currentItem.hide();this._createPlaceholder();b.containment&&this._setContainment();if(b.cursor){if(d("body").css("cursor"))this._storedCursor=d("body").css("cursor");d("body").css("cursor",b.cursor)}if(b.opacity){if(this.helper.css("opacity"))this._storedOpacity=this.helper.css("opacity");this.helper.css("opacity",b.opacity)}
15591if(b.zIndex){if(this.helper.css("zIndex"))this._storedZIndex=this.helper.css("zIndex");this.helper.css("zIndex",b.zIndex)}if(this.scrollParent[0]!= 15592document&&this.scrollParent[0].tagName!="HTML")this.overflowOffset=this.scrollParent.offset();this._trigger("start",a,this._uiHash());this._preserveHelperProportions||this._cacheHelperProportions();if(!c)for(c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("activate",a,e._uiHash(this));if(d.ui.ddmanager)d.ui.ddmanager.current=this;d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(a); 15593return true},_mouseDrag:function(a){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs)this.lastPositionAbs=this.positionAbs;if(this.options.scroll){var b=this.options,c=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if(this.overflowOffset.top+this.scrollParent[0].offsetHeight-a.pageY<b.scrollSensitivity)this.scrollParent[0].scrollTop=c=this.scrollParent[0].scrollTop+b.scrollSpeed;else if(a.pageY-this.overflowOffset.top< 15594b.scrollSensitivity)this.scrollParent[0].scrollTop=c=this.scrollParent[0].scrollTop-b.scrollSpeed;if(this.overflowOffset.left+this.scrollParent[0].offsetWidth-a.pageX<b.scrollSensitivity)this.scrollParent[0].scrollLeft=c=this.scrollParent[0].scrollLeft+b.scrollSpeed;else if(a.pageX-this.overflowOffset.left<b.scrollSensitivity)this.scrollParent[0].scrollLeft=c=this.scrollParent[0].scrollLeft-b.scrollSpeed}else{if(a.pageY-d(document).scrollTop()<b.scrollSensitivity)c=d(document).scrollTop(d(document).scrollTop()- 15595b.scrollSpeed);else if(d(window).height()-(a.pageY-d(document).scrollTop())<b.scrollSensitivity)c=d(document).scrollTop(d(document).scrollTop()+b.scrollSpeed);if(a.pageX-d(document).scrollLeft()<b.scrollSensitivity)c=d(document).scrollLeft(d(document).scrollLeft()-b.scrollSpeed);else if(d(window).width()-(a.pageX-d(document).scrollLeft())<b.scrollSensitivity)c=d(document).scrollLeft(d(document).scrollLeft()+b.scrollSpeed)}c!==false&&d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this, 15596a)}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";for(b=this.items.length-1;b>=0;b--){c=this.items[b];var e=c.item[0],f=this._intersectsWithPointer(c);if(f)if(e!=this.currentItem[0]&&this.placeholder[f==1?"next":"prev"]()[0]!=e&&!d.ui.contains(this.placeholder[0],e)&&(this.options.type=="semi-dynamic"?!d.ui.contains(this.element[0], 15597e):true)){this.direction=f==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(c))this._rearrange(a,c);else break;this._trigger("change",a,this._uiHash());break}}this._contactContainers(a);d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);this._trigger("sort",a,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(a,b){if(a){d.ui.ddmanager&&!this.options.dropBehaviour&&d.ui.ddmanager.drop(this,a);if(this.options.revert){var c=this;b=c.placeholder.offset(); 15598c.reverting=true;d(this.helper).animate({left:b.left-this.offset.parent.left-c.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:b.top-this.offset.parent.top-c.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){c._clear(a)})}else this._clear(a,b);return false}},cancel:function(){var a=this;if(this.dragging){this._mouseUp({target:null});this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"): 15599this.currentItem.show();for(var b=this.containers.length-1;b>=0;b--){this.containers[b]._trigger("deactivate",null,a._uiHash(this));if(this.containers[b].containerCache.over){this.containers[b]._trigger("out",null,a._uiHash(this));this.containers[b].containerCache.over=0}}}if(this.placeholder){this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove();d.extend(this,{helper:null, 15600dragging:false,reverting:false,_noFinalSort:null});this.domPosition.prev?d(this.domPosition.prev).after(this.currentItem):d(this.domPosition.parent).prepend(this.currentItem)}return this},serialize:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};d(b).each(function(){var e=(d(a.item||this).attr(a.attribute||"id")||"").match(a.expression||/(.+)[-=_](.+)/);if(e)c.push((a.key||e[1]+"[]")+"="+(a.key&&a.expression?e[1]:e[2]))});!c.length&&a.key&&c.push(a.key+"=");return c.join("&")}, 15601toArray:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};b.each(function(){c.push(d(a.item||this).attr(a.attribute||"id")||"")});return c},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,e=this.positionAbs.top,f=e+this.helperProportions.height,g=a.left,h=g+a.width,i=a.top,k=i+a.height,j=this.offset.click.top,l=this.offset.click.left;j=e+j>i&&e+j<k&&b+l>g&&b+l<h;return this.options.tolerance=="pointer"||this.options.forcePointerForContainers|| 15602this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>a[this.floating?"width":"height"]?j:g<b+this.helperProportions.width/2&&c-this.helperProportions.width/2<h&&i<e+this.helperProportions.height/2&&f-this.helperProportions.height/2<k},_intersectsWithPointer:function(a){var b=d.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,a.top,a.height);a=d.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,a.left,a.width);b=b&&a;a=this._getDragVerticalDirection(); 15603var c=this._getDragHorizontalDirection();if(!b)return false;return this.floating?c&&c=="right"||a=="down"?2:1:a&&(a=="down"?2:1)},_intersectsWithSides:function(a){var b=d.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,a.top+a.height/2,a.height);a=d.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,a.left+a.width/2,a.width);var c=this._getDragVerticalDirection(),e=this._getDragHorizontalDirection();return this.floating&&e?e=="right"&&a||e=="left"&&!a:c&&(c=="down"&&b||c=="up"&&!b)}, 15604_getDragVerticalDirection:function(){var a=this.positionAbs.top-this.lastPositionAbs.top;return a!=0&&(a>0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){this._refreshItems(a);this.refreshPositions();return this},_connectWith:function(){var a=this.options;
15604return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(a){var b=[],c=[],e=this._connectWith(); 15605if(e&&a)for(a=e.length-1;a>=0;a--)for(var f=d(e[a]),g=f.length-1;g>=0;g--){var h=d.data(f[g],"sortable");if(h&&h!=this&&!h.options.disabled)c.push([d.isFunction(h.options.items)?h.options.items.call(h.element):d(h.options.items,h.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),h])}c.push([d.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):d(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), 15606this]);for(a=c.length-1;a>=0;a--)c[a][0].each(function(){b.push(this)});return d(b)},_removeCurrentsFromItems:function(){for(var a=this.currentItem.find(":data(sortable-item)"),b=0;b<this.items.length;b++)for(var c=0;c<a.length;c++)a[c]==this.items[b].item[0]&&this.items.splice(b,1)},_refreshItems:function(a){this.items=[];this.containers=[this];var b=this.items,c=[[d.isFunction(this.options.items)?this.options.items.call(this.element[0],a,{item:this.currentItem}):d(this.options.items,this.element), 15607this]],e=this._connectWith();if(e)for(var f=e.length-1;f>=0;f--)for(var g=d(e[f]),h=g.length-1;h>=0;h--){var i=d.data(g[h],"sortable");if(i&&i!=this&&!i.options.disabled){c.push([d.isFunction(i.options.items)?i.options.items.call(i.element[0],a,{item:this.currentItem}):d(i.options.items,i.element),i]);this.containers.push(i)}}for(f=c.length-1;f>=0;f--){a=c[f][1];e=c[f][0];h=0;for(g=e.length;h<g;h++){i=d(e[h]);i.data("sortable-item",a);b.push({item:i,instance:a,width:0,height:0,left:0,top:0})}}},refreshPositions:function(a){if(this.offsetParent&& 15608this.helper)this.offset.parent=this._getParentOffset();for(var b=this.items.length-1;b>=0;b--){var c=this.items[b];if(!(c.instance!=this.currentContainer&&this.currentContainer&&c.item[0]!=this.currentItem[0])){var e=this.options.toleranceElement?d(this.options.toleranceElement,c.item):c.item;if(!a){c.width=e.outerWidth(false);c.height=e.outerHeight(false)}e=e.offset();c.left=e.left;c.top=e.top}}
15608if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(b= 15609this.containers.length-1;b>=0;b--){e=this.containers[b].element.offset();this.containers[b].containerCache.left=e.left;this.containers[b].containerCache.top=e.top;this.containers[b].containerCache.width=this.containers[b].element.outerWidth(false);this.containers[b].containerCache.height=this.containers[b].element.outerHeight(false)}return this},_createPlaceholder:function(a){var b=a||this,c=b.options;if(!c.placeholder||c.placeholder.constructor==String){var e=c.placeholder;c.placeholder={element:function(){var f= 15610d(document.createElement(b.currentItem[0].nodeName)).addClass(e||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!e)f.style.visibility="hidden";return f},update:function(f,g){if(!(e&&!c.forcePlaceholderSize)){g.height()||g.height(b.currentItem.innerHeight()-parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10));g.width()||g.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")|| 156110,10))}}}}b.placeholder=d(c.placeholder.element.call(b.element,b.currentItem));b.currentItem.after(b.placeholder);c.placeholder.update(b,b.placeholder)},_contactContainers:function(a){for(var b=null,c=null,e=this.containers.length-1;e>=0;e--)if(!d.ui.contains(this.currentItem[0],this.containers[e].element[0]))if(this._intersectsWith(this.containers[e].containerCache)){if(!(b&&d.ui.contains(this.containers[e].element[0],b.element[0]))){b=this.containers[e];c=e}}else if(this.containers[e].containerCache.over){this.containers[e]._trigger("out", 15612a,this._uiHash(this));this.containers[e].containerCache.over=0}if(b)if(this.containers.length===1){this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}else if(this.currentContainer!=this.containers[c]){b=1E4;e=null;for(var f=this.positionAbs[this.containers[c].floating?"left":"top"],g=this.items.length-1;g>=0;g--)if(d.ui.contains(this.containers[c].element[0],this.items[g].item[0])){var h=this.items[g][this.containers[c].floating?"left":"top"];if(Math.abs(h- 15613f)<b){b=Math.abs(h-f);e=this.items[g]}}if(e||this.options.dropOnEmpty){this.currentContainer=this.containers[c];e?this._rearrange(a,e,null,true):this._rearrange(a,null,this.containers[c].element,true);this._trigger("change",a,this._uiHash());this.containers[c]._trigger("change",a,this._uiHash(this));this.options.placeholder.update(this.currentContainer,this.placeholder);this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}}},_createHelper:function(a){var b= 15614this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a,this.currentItem])):b.helper=="clone"?this.currentItem.clone():this.currentItem;a.parents("body").length||d(b.appendTo!="parent"?b.appendTo:this.currentItem[0].parentNode)[0].appendChild(a[0]);if(a[0]==this.currentItem[0])this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")};if(a[0].style.width== 15615""||b.forceHelperSize)a.width(this.currentItem.width());if(a[0].style.height==""||b.forceHelperSize)a.height(this.currentItem.height());return a},_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top= 15616this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&false)a= 15617{top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),
1561710)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.currentItem.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"), 1561810)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(false),height:this.helper.outerHeight(false)}},_setContainment:function(){var a=this.options;if(a.containment=="parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,d(a.containment=="document"? 15619document:window).width()-this.helperProportions.width-this.margins.left,(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)){var b=d(a.containment)[0];a=d(a.containment).offset();var c=d(b).css("overflow")!="hidden";this.containment=[a.left+(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0)-this.margins.left,a.top+(parseInt(d(b).css("borderTopWidth"), 1562010)||0)+(parseInt(d(b).css("paddingTop"),10)||0)-this.margins.top,a.left+(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,a.top+(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"),10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(a,b){if(!b)b= 15621this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(c[0].tagName);return{top:b.top+this.offset.relative.top*a+this.offset.parent.top*a-(false&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(false&& 15622this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(c[0].tagName);if(this.cssPosition=="relative"&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0]))this.offset.relative=this._getRelativeOffset(); 15623var f=a.pageX,g=a.pageY;if(this.originalPosition){if(this.containment){if(a.pageX-this.offset.click.left<this.containment[0])f=this.containment[0]+this.offset.click.left;if(a.pageY-this.offset.click.top<this.containment[1])g=this.containment[1]+this.offset.click.top;if(a.pageX-this.offset.click.left>this.containment[2])f=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g- 15624this.originalPageY)/b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?g:!(g-this.offset.click.top<this.containment[1])?g-b.grid[1]:g+b.grid[1]:g;f=this.originalPageX+Math.round((f-this.originalPageX)/b.grid[0])*b.grid[0];f=this.containment?!(f-this.offset.click.left<this.containment[0]||f-this.offset.click.left>this.containment[2])?f:!(f-this.offset.click.left<this.containment[0])?f-b.grid[0]:f+b.grid[0]:f}}return{top:g- 15625this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(false&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:c.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(false&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:c.scrollLeft())}},_rearrange:function(a,b,c,e){c?c[0].appendChild(this.placeholder[0]):b.item[0].parentNode.insertBefore(this.placeholder[0], 15626this.direction=="down"?b.item[0]:b.item[0].nextSibling);this.counter=this.counter?++this.counter:1;var f=this,g=this.counter;window.setTimeout(function(){g==f.counter&&f.refreshPositions(!e)},0)},_clear:function(a,b){this.reverting=false;var c=[];!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem);this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var e in this._storedCSS)if(this._storedCSS[e]=="auto"||this._storedCSS[e]=="static")this._storedCSS[e]= 15627"";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!b&&c.push(function(f){this._trigger("receive",f,this._uiHash(this.fromOutside))});if((this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!b)c.push(function(f){this._trigger("update",f,this._uiHash())});if(!d.ui.contains(this.element[0],this.currentItem[0])){b||c.push(function(f){this._trigger("remove", 15628f,this._uiHash())});for(e=this.containers.length-1;e>=0;e--)if(d.ui.contains(this.containers[e].element[0],this.currentItem[0])&&!b){c.push(function(f){return function(g){f._trigger("receive",g,this._uiHash(this))}}.call(this,this.containers[e]));c.push(function(f){return function(g){f._trigger("update",g,this._uiHash(this))}}.call(this,this.containers[e]))}}for(e=this.containers.length-1;e>=0;e--){b||c.push(function(f){return function(g){f._trigger("deactivate",g,this._uiHash(this))}}.call(this, 15629this.containers[e]));if(this.containers[e].containerCache.over){c.push(function(f){return function(g){f._trigger("out",g,this._uiHash(this))}}.call(this,this.containers[e]));this.containers[e].containerCache.over=0}}this._storedCursor&&d("body").css("cursor",this._storedCursor);this._storedOpacity&&this.helper.css("opacity",this._storedOpacity);if(this._storedZIndex)this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex);this.dragging=false;if(this.cancelHelperRemoval){if(!b){this._trigger("beforeStop", 15630a,this._uiHash());for(e=0;e<c.length;e++)c[e].call(this,a);this._trigger("stop",a,this._uiHash())}return false}b||this._trigger("beforeStop",a,this._uiHash());this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.helper[0]!=this.currentItem[0]&&this.helper.remove();this.helper=null;if(!b){for(e=0;e<c.length;e++)c[e].call(this,a);this._trigger("stop",a,this._uiHash())}this.fromOutside=false;return true},_trigger:function(){d.Widget.prototype._trigger.apply(this,arguments)===false&&this.cancel()}, 15631_uiHash:function(a){var b=a||this;return{helper:b.helper,placeholder:b.placeholder||d([]),position:b.position,originalPosition:b.originalPosition,offset:b.positionAbs,item:b.currentItem,sender:a?a.element:null}}});d.extend(d.ui.sortable,{version:"1.8.14"})})(jQuery); 15632;/* 15633 * jQuery UI Accordion 1.8.14 15634 * 15635 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 15636 * Dual licensed under the MIT or GPL Version 2 licenses. 15637 * http://jquery.org/license 15638 * 15639 * http://docs.jquery.com/UI/Accordion 15640 * 15641 * Depends: 15642 * jquery.ui.core.js 15643 * jquery.ui.widget.js 15644 */ 15645(function(c){c.widget("ui.accordion",{options:{active:0,animated:"slide",autoHeight:true,clearStyle:false,collapsible:false,event:"click",fillSpace:false,header:"> li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:false,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var a=this,b=a.options;a.running=0;a.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix"); 15646a.headers=a.element.find(b.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){b.disabled||c(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){b.disabled||c(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){b.disabled||c(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){b.disabled||c(this).removeClass("ui-state-focus")});a.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom"); 15647if(b.navigation){var d=a.element.find("a").filter(b.navigationFilter).eq(0);if(d.length){var h=d.closest(".ui-accordion-header");a.active=h.length?h:d.closest(".ui-accordion-content").prev()}}a.active=a._findActive(a.active||b.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");a.active.next().addClass("ui-accordion-content-active");a._createIcons();a.resize();a.element.attr("role","tablist");a.headers.attr("role","tab").bind("keydown.accordion", 15648function(f){return a._keydown(f)}).next().attr("role","tabpanel");a.headers.not(a.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide();a.active.length?a.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):a.headers.eq(0).attr("tabIndex",0);false||a.headers.find("a").attr("tabIndex",-1);b.event&&a.headers.bind(b.event.split(" ").join(".accordion ")+".accordion",function(f){a._clickHandler.call(a,f,this);f.preventDefault()})},_createIcons:function(){var a= 15649this.options;if(a.icons){c("<span></span>").addClass("ui-icon "+a.icons.header).prependTo(this.headers);this.active.children(".ui-icon").toggleClass(a.icons.header).toggleClass(a.icons.headerSelected);this.element.addClass("ui-accordion-icons")}},_destroyIcons:function(){this.headers.children(".ui-icon").remove();this.element.removeClass("ui-accordion-icons")},destroy:function(){var a=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role");this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex"); 15650this.headers.find("a").removeAttr("tabIndex");this._destroyIcons();var b=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");if(a.autoHeight||a.fillHeight)b.css("height","");return c.Widget.prototype.destroy.call(this)},_setOption:function(a,b){c.Widget.prototype._setOption.apply(this,arguments);a=="active"&&this.activate(b);if(a=="icons"){this._destroyIcons(); 15651b&&this._createIcons()}if(a=="disabled")this.headers.add(this.headers.next())[b?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")}
15651,_keydown:function(a){if(!(this.options.disabled||a.altKey||a.ctrlKey)){var b=c.ui.keyCode,d=this.headers.length,h=this.headers.index(a.target),f=false;switch(a.keyCode){case b.RIGHT:case b.DOWN:f=this.headers[(h+1)%d];break;case b.LEFT:case b.UP:f=this.headers[(h-1+d)%d];break;case b.SPACE:case b.ENTER:this._clickHandler({target:a.target},a.target); 15652a.preventDefault()}if(f){c(a.target).attr("tabIndex",-1);c(f).attr("tabIndex",0);f.focus();return false}return true}},resize:function(){var a=this.options,b;if(a.fillSpace){if(false){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}b=this.element.parent().height();false&&this.element.parent().css("overflow",d);this.headers.each(function(){b-=c(this).outerHeight(true)});this.headers.next().each(function(){c(this).height(Math.max(0,b-c(this).innerHeight()+ 15653c(this).height()))}).css("overflow","auto")}else if(a.autoHeight){b=0;this.headers.next().each(function(){b=Math.max(b,c(this).height("").height())}).height(b)}return this},activate:function(a){this.options.active=a;a=this._findActive(a)[0];this._clickHandler({target:a},a);return this},_findActive:function(a){return a?typeof a==="number"?this.headers.filter(":eq("+a+")"):this.headers.not(this.headers.not(a)):a===false?c([]):this.headers.filter(":eq(0)")},_clickHandler:function(a,b){var d=this.options; 15654if(!d.disabled)if(a.target){a=c(a.currentTarget||b);b=a[0]===this.active[0];d.active=d.collapsible&&b?false:this.headers.index(a);if(!(this.running||!d.collapsible&&b)){var h=this.active;j=a.next();g=this.active.next();e={options:d,newHeader:b&&d.collapsible?c([]):a,oldHeader:this.active,newContent:b&&d.collapsible?c([]):j,oldContent:g};var f=this.headers.index(this.active[0])>this.headers.index(a[0]);this.active=b?c([]):a;this._toggle(j,g,e,b,f);h.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header); 15655if(!b){a.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected);a.next().addClass("ui-accordion-content-active")}}}else if(d.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);this.active.next().addClass("ui-accordion-content-active");var g=this.active.next(), 15656e={options:d,newHeader:c([]),oldHeader:d.active,newContent:c([]),oldContent:g},j=this.active=c([]);this._toggle(j,g,e)}},_toggle:function(a,b,d,h,f){var g=this,e=g.options;g.toShow=a;g.toHide=b;g.data=d;var j=function(){if(g)return g._completed.apply(g,arguments)};g._trigger("changestart",null,g.data);g.running=b.size()===0?a.size():b.size();if(e.animated){d={};d=e.collapsible&&h?{toShow:c([]),toHide:b,complete:j,down:f,autoHeight:e.autoHeight||e.fillSpace}:{toShow:a,toHide:b,complete:j,down:f,autoHeight:e.autoHeight|| 15657e.fillSpace};if(!e.proxied)e.proxied=e.animated;if(!e.proxiedDuration)e.proxiedDuration=e.duration;e.animated=c.isFunction(e.proxied)?e.proxied(d):e.proxied;e.duration=c.isFunction(e.proxiedDuration)?e.proxiedDuration(d):e.proxiedDuration;h=c.ui.accordion.animations;var i=e.duration,k=e.animated;if(k&&!h[k]&&!c.easing[k])k="slide";h[k]||(h[k]=function(l){this.slide(l,{easing:k,duration:i||700})});h[k](d)}else{if(e.collapsible&&h)a.toggle();else{b.hide();a.show()}j(true)}b.prev().attr({"aria-expanded":"false", 15658"aria-selected":"false",tabIndex:-1}).blur();a.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;if(!this.running){this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""});this.toHide.removeClass("ui-accordion-content-active");if(this.toHide.length)this.toHide.parent()[0].className=this.toHide.parent()[0].className;this._trigger("change",null,this.data)}}});c.extend(c.ui.accordion,{version:"1.8.14", 15659animations:{slide:function(a,b){a=c.extend({easing:"swing",duration:300},a,b);if(a.toHide.size())if(a.toShow.size()){var d=a.toShow.css("overflow"),h=0,f={},g={},e;b=a.toShow;e=b[0].style.width;b.width(parseInt(b.parent().width(),10)-parseInt(b.css("paddingLeft"),10)-parseInt(b.css("paddingRight"),10)-(parseInt(b.css("borderLeftWidth"),10)||0)-(parseInt(b.css("borderRightWidth"),10)||0));c.each(["height","paddingTop","paddingBottom"],function(j,i){g[i]="hide";j=(""+c.css(a.toShow[0],i)).match(/^([\d+-.]+)(.*)$/); 15660f[i]={value:j[1],unit:j[2]||"px"}});a.toShow.css({height:0,overflow:"hidden"}).show();a.toHide.filter(":hidden").each(a.complete).end().filter(":visible").animate(g,{step:function(j,i){if
15660(i.prop=="height")h=i.end-i.start===0?0:(i.now-i.start)/(i.end-i.start);a.toShow[0].style[i.prop]=h*f[i.prop].value+f[i.prop].unit},duration:a.duration,easing:a.easing,complete:function(){a.autoHeight||a.toShow.css("height","");a.toShow.css({width:e,overflow:d});a.complete()}})}else a.toHide.animate({height:"hide", 15661paddingTop:"hide",paddingBottom:"hide"},a);else a.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},a)},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1E3:200})}}})})(jQuery); 15662;/* 15663 * jQuery UI Autocomplete 1.8.14 15664 * 15665 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 15666 * Dual licensed under the MIT or GPL Version 2 licenses. 15667 * http://jquery.org/license 15668 * 15669 * http://docs.jquery.com/UI/Autocomplete 15670 * 15671 * Depends: 15672 * jquery.ui.core.js 15673 * jquery.ui.widget.js 15674 * jquery.ui.position.js 15675 */ 15676(function(d){var e=0;d.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:false,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var a=this,b=this.element[0].ownerDocument,g;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(!(a.options.disabled||a.element.attr("readonly"))){g= 15677false;var f=d.ui.keyCode;switch(c.keyCode){case f.PAGE_UP:a._move("previousPage",c);break;case f.PAGE_DOWN:a._move("nextPage",c);break;case f.UP:a._move("previous",c);c.preventDefault();break;case f.DOWN:a._move("next",c);c.preventDefault();break;case f.ENTER:case f.NUMPAD_ENTER:if(a.menu.active){g=true;c.preventDefault()}case f.TAB:if(!a.menu.active)return;a.menu.select(c);break;case f.ESCAPE:a.element.val(a.term);a.close(c);break;default:clearTimeout(a.searching);a.searching=setTimeout(function(){if(a.term!= 15678a.element.val()){a.selectedItem=null;a.search(null,c)}},a.options.delay);break}}}).bind("keypress.autocomplete",function(c){if(g){g=false;c.preventDefault()}}).bind("focus.autocomplete",function(){if(!a.options.disabled){a.selectedItem=null;a.previous=a.element.val()}}).bind("blur.autocomplete",function(c){if(!a.options.disabled){clearTimeout(a.searching);a.closing=setTimeout(function(){a.close(c);a._change(c)},150)}});this._initSource();this.response=function(){return a._response.apply(a,arguments)}; 15679this.menu=d("<ul></ul>").addClass("ui-autocomplete").appendTo(d(this.options.appendTo||"body",b)[0]).on('mousedown', function(c){var f=a.menu.element[0];d(c.target).closest(".ui-menu-item").length||setTimeout(function(){d(document).one("mousedown",function(h){h.target!==a.element[0]&&h.target!==f&&!d.ui.contains(f,h.target)&&a.close()})},1);setTimeout(function(){clearTimeout(a.closing)},13)}).menu({focus:function(c,f){f=f.item.data("item.autocomplete");false!==a._trigger("focus",c,{item:f})&&/^key/.test(c.originalEvent.type)&& 15680a.element.val(f.value)},selected:function(c,f){var h=f.item.data("item.autocomplete"),i=a.previous;if(a.element[0]!==b.activeElement){a.element.focus();a.previous=i;setTimeout(function(){a.previous=i;a.selectedItem=h},1)}false!==a._trigger("select",c,{item:h})&&a.element.val(h.value);a.term=a.element.val();a.close(c);a.selectedItem=h},blur:function(){a.menu.element.is(":visible")&&a.element.val()!==a.term&&a.element.val(a.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu"); 15681d.fn.bgiframe&&this.menu.element.bgiframe()},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup");this.menu.element.remove();d.Widget.prototype.destroy.call(this)},_setOption:function(a,b){d.Widget.prototype._setOption.apply(this,arguments);a==="source"&&this._initSource();if(a==="appendTo")this.menu.element.appendTo(d(b||"body",this.element[0].ownerDocument)[0]);a==="disabled"&& 15682b&&this.xhr&&this.xhr.abort()},_initSource:function(){var a=this,b,g;if(d.isArray(this.options.source)){b=this.options.source;this.source=function(c,f){f(d.ui.autocomplete.filter(b,c.term))}}else if(typeof this.options.source==="string"){g=this.options.source;this.source=function(c,f){a.xhr&&a.xhr.abort();a.xhr=d.ajax({url:g,data:c,dataType:"json",autocompleteRequest:++e,success:function(h){this.autocompleteRequest===e&&f(h)},error:function(){this.autocompleteRequest===e&&f([])}})}}else this.source= 15683this.options.source},search:function(a,b){a=a!=null?a:this.element.val();this.term=this.element.val();if(a.length<this.options.minLength)return this.close(b);clearTimeout(this.closing);if(this._trigger("search",b)!==false)return this._search(a)},_search:function(a){this.pending++;this.element.addClass("ui-autocomplete-loading");this.source({term:a},this.response)}
15683,_response:function(a){if(!this.options.disabled&&a&&a.length){a=this._normalize(a);this._suggest(a);this._trigger("open")}else this.close(); 15684this.pending--;this.pending||this.element.removeClass("ui-autocomplete-loading")},close:function(a){clearTimeout(this.closing);if(this.menu.element.is(":visible")){this.menu.element.hide();this.menu.deactivate();this._trigger("close",a)}},_change:function(a){this.previous!==this.element.val()&&this._trigger("change",a,{item:this.selectedItem})},_normalize:function(a){if(a.length&&a[0].label&&a[0].value)return a;return d.map(a,function(b){if(typeof b==="string")return{label:b,value:b};return d.extend({label:b.label|| 15685b.value,value:b.value||b.label},b)})},_suggest:function(a){var b=this.menu.element.empty().zIndex(this.element.zIndex()+1);this._renderMenu(b,a);this.menu.deactivate();this.menu.refresh();b.show();this._resizeMenu();b.position(d.extend({of:this.element},this.options.position));this.options.autoFocus&&this.menu.next(new d.Event("mouseover"))},_resizeMenu:function(){var a=this.menu.element;a.outerWidth(Math.max(a.width("").outerWidth(false),this.element.outerWidth(false)))},_renderMenu:function(a,b){var g=this; 15686d.each(b,function(c,f){g._renderItem(a,f)})},_renderItem:function(a,b){return d("<li></li>").data("item.autocomplete",b).append(d("<a></a>").text(b.label)).appendTo(a)},_move:function(a,b){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term);this.menu.deactivate()}else this.menu[a](b);else this.search(null,b)},widget:function(){return this.menu.element}});d.extend(d.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, 15687"\\$&")},filter:function(a,b){var g=new RegExp(d.ui.autocomplete.escapeRegex(b),"i");return d.grep(a,function(c){return g.test(c.label||c.value||c)})}})})(jQuery); 15688(function(d){d.widget("ui.menu",{_create:function(){var e=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(a){if(d(a.target).closest(".ui-menu-item a").length){a.preventDefault();e.select(a)}});this.refresh()},refresh:function(){var e=this;this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem").children("a").addClass("ui-corner-all").attr("tabindex", 15689-1).mouseenter(function(a){e.activate(a,d(this).parent())}).mouseleave(function(){e.deactivate()})},activate:function(e,a){this.deactivate();if(this.hasScroll()){var b=a.offset().top-this.element.offset().top,g=this.element.scrollTop(),c=this.element.height();if(b<0)this.element.scrollTop(g+b);else b>=c&&this.element.scrollTop(g+b-c+a.height())}this.active=a.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end();this._trigger("focus",e,{item:a})},deactivate:function(){if(this.active){this.active.children("a").removeClass("ui-state-hover").removeAttr("id"); 15690this._trigger("blur");this.active=null}},next:function(e){this.move("next",".ui-menu-item:first",e)},previous:function(e){this.move("prev",".ui-menu-item:last",e)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(e,a,b){if(this.active){e=this.active[e+"All"](".ui-menu-item").eq(0);e.length?this.activate(b,e):this.activate(b,this.element.children(a))}else this.activate(b, 15691this.element.children(a))},nextPage:function(e){if(this.hasScroll())if(!this.active||this.last())this.activate(e,this.element.children(".ui-menu-item:first"));else{var a=this.active.offset().top,b=this.element.height(),g=this.element.children(".ui-menu-item").filter(function(){var c=d(this).offset().top-a-b+d(this).height();return c<10&&c>-10});g.length||(g=this.element.children(".ui-menu-item:last"));this.activate(e,g)}else this.activate(e,this.element.children(".ui-menu-item").filter(!this.active|| 15692this.last()?":first":":last"))},previousPage:function(e){if(this.hasScroll())if(!this.active||this.first())this.activate(e,this.element.children(".ui-menu-item:last"));else{var a=this.active.offset().top,b=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var g=d(this).offset().top-a+b-d(this).height();return g<10&&g>-10});result.length||(result=this.element.children(".ui-menu-item:first"));this.activate(e,result)}else this.activate(e,this.element.children(".ui-menu-item").filter(!this.active|| 15693this.first()?":last":":first"))},hasScroll:function(){return this.element.height()<this.element[d.fn.prop?"prop":"attr"]("scrollHeight")},select:function(e){this._trigger("selected",e,{item:this.active})}})})(jQuery); 15694;/* 15695 * jQuery UI Button 1.8.14 15696 * 15697 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 15698 * Dual licensed under the MIT or GPL Version 2 licenses. 15699 * http://jquery.org/license 15700 * 15701 * http://docs.jquery.com/UI/Button 15702 * 15703 * Depends: 15704 * jquery.ui.core.js 15705 * jquery.ui.widget.js 15706 */ 15707(function(b){var h,i,j,g,l=function(){var a=b(this).find(":ui-button");setTimeout(function(){a.button("refresh")},1)},k=function(a){var c=a.name,e=a.form,f=b([]);if(c)f=e?b(e).find("[name='"+c+"']"):b("[name='"+c+"']",a.ownerDocument).filter(function(){return!this.form});return f};b.widget("ui.button",{options:{disabled:null,text:true,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset.button").bind("reset.button",l);if(typeof this.options.disabled!== 15708"boolean")this.options.disabled=this.element.attr("disabled");this._determineButtonType();this.hasTitle=!!this.buttonElement.attr("title");var a=this,c=this.options,e=this.type==="checkbox"||this.type==="radio",f="ui-state-hover"+(!e?" ui-state-active":"");
15708if(c.label===null)c.label=this.buttonElement.html();if(this.element.is(":disabled"))c.disabled=true;this.buttonElement.addClass("ui-button ui-widget ui-state-default ui-corner-all").attr("role","button").bind("mouseenter.button",function(){if(!c.disabled){b(this).addClass("ui-state-hover"); 15709this===h&&b(this).addClass("ui-state-active")}}).bind("mouseleave.button",function(){c.disabled||b(this).removeClass(f)}).bind("click.button",function(d){if(c.disabled){d.preventDefault();d.stopImmediatePropagation()}});this.element.bind("focus.button",function(){a.buttonElement.addClass("ui-state-focus")}).bind("blur.button",function(){a.buttonElement.removeClass("ui-state-focus")});if(e){this.element.bind("change.button",function(){g||a.refresh()});this.buttonElement.bind("mousedown.button",function(d){if(!c.disabled){g= 15710false;i=d.pageX;j=d.pageY}}).bind("mouseup.button",function(d){if(!c.disabled)if(i!==d.pageX||j!==d.pageY)g=true})}if(this.type==="checkbox")this.buttonElement.bind("click.button",function(){if(c.disabled||g)return false;b(this).toggleClass("ui-state-active");a.buttonElement.attr("aria-pressed",a.element[0].checked)});else if(this.type==="radio")this.buttonElement.bind("click.button",function(){if(c.disabled||g)return false;b(this).addClass("ui-state-active");a.buttonElement.attr("aria-pressed",true); 15711var d=a.element[0];k(d).not(d).map(function(){return b(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed",false)});else{this.buttonElement.bind("mousedown.button",function(){if(c.disabled)return false;b(this).addClass("ui-state-active");h=this;b(document).one("mouseup",function(){h=null})}).bind("mouseup.button",function(){if(c.disabled)return false;b(this).removeClass("ui-state-active")}).bind("keydown.button",function(d){if(c.disabled)return false;if(d.keyCode==b.ui.keyCode.SPACE|| 15712d.keyCode==b.ui.keyCode.ENTER)b(this).addClass("ui-state-active")}).bind("keyup.button",function(){b(this).removeClass("ui-state-active")});this.buttonElement.is("a")&&this.buttonElement.keyup(function(d){d.keyCode===b.ui.keyCode.SPACE&&b(this).click()})}this._setOption("disabled",c.disabled);this._resetButton()},_determineButtonType:function(){this.type=this.element.is(":checkbox")?"checkbox":this.element.is(":radio")?"radio":this.element.is("input")?"input":"button";if(this.type==="checkbox"||this.type=== 15713"radio"){var a=this.element.parents().filter(":last"),c="label[for="+this.element.attr("id")+"]";this.buttonElement=a.find(c);if(!this.buttonElement.length){a=a.length?a.siblings():this.element.siblings();this.buttonElement=a.filter(c);if(!this.buttonElement.length)this.buttonElement=a.find(c)}this.element.addClass("ui-helper-hidden-accessible");(a=this.element.is(":checked"))&&this.buttonElement.addClass("ui-state-active");this.buttonElement.attr("aria-pressed",a)}else this.buttonElement=this.element}, 15714widget:function(){return this.buttonElement},destroy:function(){this.element.removeClass("ui-helper-hidden-accessible");this.buttonElement.removeClass("ui-button ui-widget ui-state-default ui-corner-all ui-state-hover ui-state-active ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only").removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html());this.hasTitle||this.buttonElement.removeAttr("title"); 15715b.Widget.prototype.destroy.call(this)},_setOption:function(a,c){b.Widget.prototype._setOption.apply(this,arguments);if(a==="disabled")c?this.element.attr("disabled",true):this.element.removeAttr("disabled");else this._resetButton()},refresh:function(){var a=this.element.is(":disabled");a!==this.options.disabled&&this._setOption("disabled",a);if(this.type==="radio")k(this.element[0]).each(function(){b(this).is(":checked")?b(this).button("widget").addClass("ui-state-active").attr("aria-pressed",true): 15716b(this).button("widget").removeClass("ui-state-active").attr("aria-pressed",false)});else if(this.type==="checkbox")this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed",true):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed",false)}
15716,_resetButton:function(){if(this.type==="input")this.options.label&&this.element.val(this.options.label);else{var a=this.buttonElement.removeClass("ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only"), 15717c=b("<span></span>").addClass("ui-button-text").html(this.options.label).appendTo(a.empty()).text(),e=this.options.icons,f=e.primary&&e.secondary,d=[];if(e.primary||e.secondary){if(this.options.text)d.push("ui-button-text-icon"+(f?"s":e.primary?"-primary":"-secondary"));e.primary&&a.prepend("<span class='ui-button-icon-primary ui-icon "+e.primary+"'></span>");e.secondary&&a.append("<span class='ui-button-icon-secondary ui-icon "+e.secondary+"'></span>");if(!this.options.text){d.push(f?"ui-button-icons-only": 15718"ui-button-icon-only");this.hasTitle||a.attr("title",c)}}else d.push("ui-button-text-only");a.addClass(d.join(" "))}}});b.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(a,c){a==="disabled"&&this.buttons.button("option",a,c);b.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){var a=this.element.css("direction")=== 15719"ltr";this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return b(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(a?"ui-corner-left":"ui-corner-right").end().filter(":last").addClass(a?"ui-corner-right":"ui-corner-left").end().end()},destroy:function(){this.element.removeClass("ui-buttonset");this.buttons.map(function(){return b(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy"); 15720b.Widget.prototype.destroy.call(this)}})})(jQuery); 15721;/* 15722 * jQuery UI Dialog 1.8.14 15723 * 15724 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 15725 * Dual licensed under the MIT or GPL Version 2 licenses. 15726 * http://jquery.org/license 15727 * 15728 * http://docs.jquery.com/UI/Dialog 15729 * 15730 * Depends: 15731 * jquery.ui.core.js 15732 * jquery.ui.widget.js 15733 * jquery.ui.button.js 15734 * jquery.ui.draggable.js 15735 * jquery.ui.mouse.js 15736 * jquery.ui.position.js 15737 * jquery.ui.resizable.js 15738 */ 15739(function(c,l){var m={buttons:true,height:true,maxHeight:true,maxWidth:true,minHeight:true,minWidth:true,width:true},n={maxHeight:true,maxWidth:true,minHeight:true,minWidth:true},o={val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true,click:true};c.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false, 15740position:{my:"center",at:"center",collision:"fit",using:function(a){var b=c(this).css(a).offset().top;b<0&&c(this).css("top",a.top-b)}},resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");if(typeof this.originalTitle!=="string")this.originalTitle="";this.options.title=this.options.title||this.originalTitle;var a=this,b=a.options,d=b.title||" ",e=c.ui.dialog.getTitleId(a.element),g=(a.uiDialog=c("<div></div>")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+ 15741b.dialogClass).css({zIndex:b.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(i){if(b.closeOnEscape&&i.keyCode&&i.keyCode===c.ui.keyCode.ESCAPE){a.close(i);i.preventDefault()}}).attr({role:"dialog","aria-labelledby":e}).on('mousedown', function(i){a.moveToTop(false,i)});a.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g);var f=(a.uiDialogTitlebar=c("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g), 15742h=c('<a href="#"></a>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){h.addClass("ui-state-hover")},function(){h.removeClass("ui-state-hover")}).focus(function(){h.addClass("ui-state-focus")}).blur(function(){h.removeClass("ui-state-focus")}).click(function(i){a.close(i);return false}).appendTo(f);(a.uiDialogTitlebarCloseText=c("<span></span>")).addClass("ui-icon ui-icon-closethick").text(b.closeText).appendTo(h);c("<span></span>").addClass("ui-dialog-title").attr("id", 15743e).html(d).prependTo(f);if(c.isFunction(b.beforeclose)&&!c.isFunction(b.beforeClose))b.beforeClose=b.beforeclose;f.find("*").add(f).disableSelection();b.draggable&&c.fn.draggable&&a._makeDraggable();b.resizable&&c.fn.resizable&&a._makeResizable();a._createButtons(b.buttons);a._isOpen=false;c.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy();a.uiDialog.hide();a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"); 15744a.uiDialog.remove();a.originalTitle&&a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(a){var b=this,d,e;if(false!==b._trigger("beforeClose",a)){b.overlay&&b.overlay.destroy();
15744b.uiDialog.unbind("keypress.ui-dialog");b._isOpen=false;if(b.options.hide)b.uiDialog.hide(b.options.hide,function(){b._trigger("close",a)});else{b.uiDialog.hide();b._trigger("close",a)}c.ui.dialog.overlay.resize();if(b.options.modal){d=0;c(".ui-dialog").each(function(){if(this!== 15745b.uiDialog[0]){e=c(this).css("z-index");isNaN(e)||(d=Math.max(d,e))}});c.ui.dialog.maxZ=d}return b}},isOpen:function(){return this._isOpen},moveToTop:function(a,b){var d=this,e=d.options;if(e.modal&&!a||!e.stack&&!e.modal)return d._trigger("focus",b);if(e.zIndex>c.ui.dialog.maxZ)c.ui.dialog.maxZ=e.zIndex;if(d.overlay){c.ui.dialog.maxZ+=1;d.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=c.ui.dialog.maxZ)}a={scrollTop:d.element.attr("scrollTop"),scrollLeft:d.element.attr("scrollLeft")};c.ui.dialog.maxZ+= 157461;d.uiDialog.css("z-index",c.ui.dialog.maxZ);d.element.attr(a);d._trigger("focus",b);return d},open:function(){if(!this._isOpen){var a=this,b=a.options,d=a.uiDialog;a.overlay=b.modal?new c.ui.dialog.overlay(a):null;a._size();a._position(b.position);d.show(b.show);a.moveToTop(true);b.modal&&d.bind("keypress.ui-dialog",function(e){if(e.keyCode===c.ui.keyCode.TAB){var g=c(":tabbable",this),f=g.filter(":first");g=g.filter(":last");if(e.target===g[0]&&!e.shiftKey){f.focus(1);return false}else if(e.target=== 15747f[0]&&e.shiftKey){g.focus(1);return false}}});c(a.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus();a._isOpen=true;a._trigger("open");return a}},_createButtons:function(a){var b=this,d=false,e=c("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=c("<div></div>").addClass("ui-dialog-buttonset").appendTo(e);b.uiDialog.find(".ui-dialog-buttonpane").remove();typeof a==="object"&&a!==null&&c.each(a, 15748function(){return!(d=true)});if(d){c.each(a,function(f,h){h=c.isFunction(h)?{click:h,text:f}:h;var i=c('<button type="button"></button>').click(function(){h.click.apply(b.element[0],arguments)}).appendTo(g);c.each(h,function(j,k){if(j!=="click")j in o?i[j](k):i.attr(j,k)});c.fn.button&&i.button()});e.appendTo(b.uiDialog)}},_makeDraggable:function(){function a(f){return{position:f.position,offset:f.offset}}var b=this,d=b.options,e=c(document),g;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close", 15749handle:".ui-dialog-titlebar",containment:"document",start:function(f,h){g=d.height==="auto"?"auto":c(this).height();c(this).height(c(this).height()).addClass("ui-dialog-dragging");b._trigger("dragStart",f,a(h))},drag:function(f,h){b._trigger("drag",f,a(h))},stop:function(f,h){d.position=[h.position.left-e.scrollLeft(),h.position.top-e.scrollTop()];c(this).removeClass("ui-dialog-dragging").height(g);b._trigger("dragStop",f,a(h));c.ui.dialog.overlay.resize()}})},_makeResizable:function(a){function b(f){return{originalPosition:f.originalPosition, 15750originalSize:f.originalSize,position:f.position,size:f.size}}a=a===l?this.options.resizable:a;var d=this,e=d.options,g=d.uiDialog.css("position");a=typeof a==="string"?a:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:a,start:function(f,h){c(this).addClass("ui-dialog-resizing");d._trigger("resizeStart",f,b(h))},resize:function(f,h){d._trigger("resize", 15751f,b(h))},stop:function(f,h){c(this).removeClass("ui-dialog-resizing");e.height=c(this).height();e.width=c(this).width();d._trigger("resizeStop",f,b(h));c.ui.dialog.overlay.resize()}}).css("position",g).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(a){var b=[],d=[0,0],e;if(a){if(typeof a==="string"||typeof a==="object"&&"0"in a){b=a.split?a.split(" "): 15752[a[0],a[1]];if(b.length===1)b[1]=b[0];c.each(["left","top"],function(g,f){if(+b[g]===b[g]){d[g]=b[g];b[g]=f}});a={my:b.join(" "),at:b.join(" "),offset:d.join(" ")}}a=c.extend({},c.ui.dialog.prototype.options.position,a)}else a=c.ui.dialog.prototype.options.position;(e=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(c.extend({of:window},a));e||this.uiDialog.hide()},_setOptions:function(a){var b=this,d={},e=false;c.each(a,function(g,f){b._setOption(g,f); 15753if(g in m)e=true;if(g in n)d[g]=f});e&&this._size();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",d)},_setOption:function(a,b){var d=this,e=d.uiDialog;switch(a){case "beforeclose":a="beforeClose";break;case "buttons":d._createButtons(b);break;case "closeText":d.uiDialogTitlebarCloseText.text(""+b);break;case "dialogClass":e.removeClass(d.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b);break;case "disabled":b?e.addClass("ui-dialog-disabled"): 15754e.removeClass("ui-dialog-disabled");break;case "draggable":var g=e.is(":data(draggable)");g&&!b&&e.draggable("destroy");!g&&b&&d._makeDraggable();break;case "position":d._position(b);break;case "resizable":(g=e.is(":data(resizable)"))&&!b&&e.resizable("destroy");g&&typeof b==="string"&&e.resizable("option","handles",b);!g&&b!==false&&d._makeResizable(b);break;case "title":c(".ui-dialog-title",d.uiDialogTitlebar).html(""+(b||" "));break}c.Widget.prototype._setOption.apply(d,arguments)},_size:function(){var a= 15755this.options,b,d,e=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0});if(a.minWidth>a.width)a.width=a.minWidth;b=this.uiDialog.css({height:"auto",width:a.width}).height();d=Math.max(0,a.minHeight-b);if(a.height==="auto")if(c.support.minHeight)this.element.css({minHeight:d,height:"auto"});else{this.uiDialog.show();a=this.element.css("height","auto").height();e||this.uiDialog.hide();this.element.height(Math.max(a,d))}else this.element.height(Math.max(a.height-
15756b,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}});c.extend(c.ui.dialog,{version:"1.8.14",uuid:0,maxZ:0,getTitleId:function(a){a=a.attr("id");if(!a){this.uuid+=1;a=this.uuid}return"ui-dialog-title-"+a},overlay:function(a){this.$el=c.ui.dialog.overlay.create(a)}});c.extend(c.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "), 15757create:function(a){if(this.instances.length===0){setTimeout(function(){c.ui.dialog.overlay.instances.length&&c(document).bind(c.ui.dialog.overlay.events,function(d){if(c(d.target).zIndex()<c.ui.dialog.overlay.maxZ)return false})},1);c(document).bind("keydown.dialog-overlay",function(d){if(a.options.closeOnEscape&&d.keyCode&&d.keyCode===c.ui.keyCode.ESCAPE){a.close(d);d.preventDefault()}});c(window).bind("resize.dialog-overlay",c.ui.dialog.overlay.resize)}var b=(this.oldInstances.pop()||c("<div></div>").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(), 15758height:this.height()});c.fn.bgiframe&&b.bgiframe();this.instances.push(b);return b},destroy:function(a){var b=c.inArray(a,this.instances);b!=-1&&this.oldInstances.push(this.instances.splice(b,1)[0]);this.instances.length===0&&c([document,window]).unbind(".dialog-overlay");a.remove();var d=0;c.each(this.instances,function(){d=Math.max(d,this.css("z-index"))});this.maxZ=d},height:function(){var a,b;if(false){a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight); 15759b=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return a<b?c(window).height()+"px":a+"px"}else return c(document).height()+"px"},width:function(){var a,b;if(false){a=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth);b=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);return a<b?c(window).width()+"px":a+"px"}else return c(document).width()+"px"},resize:function(){var a=c([]);c.each(c.ui.dialog.overlay.instances,function(){a= 15760a.add(this)});a.css({width:0,height:0}).css({width:c.ui.dialog.overlay.width(),height:c.ui.dialog.overlay.height()})}});c.extend(c.ui.dialog.overlay.prototype,{destroy:function(){c.ui.dialog.overlay.destroy(this.$el)}})})(jQuery); 15761;/* 15762 * jQuery UI Slider 1.8.14 15763 * 15764 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 15765 * Dual licensed under the MIT or GPL Version 2 licenses. 15766 * http://jquery.org/license 15767 * 15768 * http://docs.jquery.com/UI/Slider 15769 * 15770 * Depends: 15771 * jquery.ui.core.js 15772 * jquery.ui.mouse.js 15773 * jquery.ui.widget.js 15774 */ 15775(function(d){d.widget("ui.slider",d.ui.mouse,{widgetEventPrefix:"slide",options:{animate:false,distance:0,max:100,min:0,orientation:"horizontal",range:false,step:1,value:0,values:null},_create:function(){var b=this,a=this.options,c=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),f=a.values&&a.values.length||1,e=[];this._mouseSliding=this._keySliding=false;this._animateOff=true;this._handleIndex=null;this._detectOrientation();this._mouseInit();this.element.addClass("ui-slider ui-slider-"+ 15776this.orientation+" ui-widget ui-widget-content ui-corner-all"+(a.disabled?" ui-slider-disabled ui-disabled":""));this.range=d([]);if(a.range){if(a.range===true){if(!a.values)a.values=[this._valueMin(),this._valueMin()];if(a.values.length&&a.values.length!==2)a.values=[a.values[0],a.values[0]]}this.range=d("<div></div>").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(a.range==="min"||a.range==="max"?" ui-slider-range-"+a.range:""))}for(var j=c.length;j<f;j+=1)e.push("<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>"); 15777this.handles=c.add(d(e.join("")).appendTo(b.element));this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(g){g.preventDefault()}).hover(function(){a.disabled||d(this).addClass("ui-state-hover")},function(){d(this).removeClass("ui-state-hover")}).focus(function(){if(a.disabled)d(this).blur();else{d(".ui-slider .ui-state-focus").removeClass("ui-state-focus");d(this).addClass("ui-state-focus")}}).blur(function(){d(this).removeClass("ui-state-focus")});this.handles.each(function(g){d(this).data("index.ui-slider-handle",
15778g)});this.handles.keydown(function(g){var k=true,l=d(this).data("index.ui-slider-handle"),i,h,m;if(!b.options.disabled){switch(g.keyCode){case d.ui.keyCode.HOME:case d.ui.keyCode.END:case d.ui.keyCode.PAGE_UP:case d.ui.keyCode.PAGE_DOWN:case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:k=false;if(!b._keySliding){b._keySliding=true;d(this).addClass("ui-state-active");i=b._start(g,l);if(i===false)return}break}m=b.options.step;i=b.options.values&&b.options.values.length? 15779(h=b.values(l)):(h=b.value());switch(g.keyCode){case d.ui.keyCode.HOME:h=b._valueMin();break;case d.ui.keyCode.END:h=b._valueMax();break;case d.ui.keyCode.PAGE_UP:h=b._trimAlignValue(i+(b._valueMax()-b._valueMin())/5);break;case d.ui.keyCode.PAGE_DOWN:h=b._trimAlignValue(i-(b._valueMax()-b._valueMin())/5);break;case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:if(i===b._valueMax())return;h=b._trimAlignValue(i+m);break;case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:if(i===b._valueMin())return;h=b._trimAlignValue(i- 15780m);break}b._slide(g,l,h);return k}}).keyup(function(g){var k=d(this).data("index.ui-slider-handle");if(b._keySliding){b._keySliding=false;b._stop(g,k);b._change(g,k);d(this).removeClass("ui-state-active")}});this._refreshValue();this._animateOff=false},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider");this._mouseDestroy(); 15781return this},_mouseCapture:function(b){var a=this.options,c,f,e,j,g;if(a.disabled)return false;this.elementSize={width:this.element.outerWidth(false),height:this.element.outerHeight(false)};this.elementOffset=this.element.offset();c=this._normValueFromMouse({x:b.pageX,y:b.pageY});f=this._valueMax()-this._valueMin()+1;j=this;this.handles.each(function(k){var l=Math.abs(c-j.values(k));if(f>l){f=l;e=d(this);g=k}});if(a.range===true&&this.values(1)===a.min){g+=1;e=d(this.handles[g])}if(this._start(b,g)===false)return false; 15782this._mouseSliding=true;j._handleIndex=g;e.addClass("ui-state-active").focus();a=e.offset();this._clickOffset=!d(b.target).parents().andSelf().is(".ui-slider-handle")?{left:0,top:0}:{left:b.pageX-a.left-e.width()/2,top:b.pageY-a.top-e.height()/2-(parseInt(e.css("borderTopWidth"),10)||0)-(parseInt(e.css("borderBottomWidth"),10)||0)+(parseInt(e.css("marginTop"),10)||0)};this.handles.hasClass("ui-state-hover")||this._slide(b,g,c);return this._animateOff=true},_mouseStart:function(){return true},_mouseDrag:function(b){var a= 15783this._normValueFromMouse({x:b.pageX,y:b.pageY});this._slide(b,this._handleIndex,a);return false},_mouseStop:function(b){this.handles.removeClass("ui-state-active");this._mouseSliding=false;this._stop(b,this._handleIndex);this._change(b,this._handleIndex);this._clickOffset=this._handleIndex=null;return this._animateOff=false},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(b){var a;if(this.orientation==="horizontal"){a= 15784this.elementSize.width;b=b.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{a=this.elementSize.height;b=b.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}a=b/a;if(a>1)a=1;if(a<0)a=0;if(this.orientation==="vertical")a=1-a;b=this._valueMax()-this._valueMin();return this._trimAlignValue(this._valueMin()+a*b)},_start:function(b,a){var c={handle:this.handles[a],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(a); 15785c.values=this.values()}return this._trigger("start",b,c)},_slide:function(b,a,c){var f;if(this.options.values&&this.options.values.length){f=this.values(a?0:1);if(this.options.values.length===2&&this.options.range===true&&(a===0&&c>f||a===1&&c<f))c=f;if(c!==this.values(a)){f=this.values();f[a]=c;b=this._trigger("slide",b,{handle:this.handles[a],value:c,values:f});this.values(a?0:1);b!==false&&this.values(a,c,true)}}else if(c!==this.value()){b=this._trigger("slide",b,{handle:this.handles[a],value:c}); 15786b!==false&&this.value(c)}},_stop:function(b,a){var c={handle:this.handles[a],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(a);c.values=this.values()}this._trigger("stop",b,c)},_change:function(b,a){if(!this._keySliding&&!this._mouseSliding){var c={handle:this.handles[a],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(a);c.values=this.values()}this._trigger("change",b,c)}},value:function(b){if(arguments.length){this.options.value= 15787this._trimAlignValue(b);this._refreshValue();this._change(null,0)}
15787else return this._value()},values:function(b,a){var c,f,e;if(arguments.length>1){this.options.values[b]=this._trimAlignValue(a);this._refreshValue();this._change(null,b)}else if(arguments.length)if(d.isArray(arguments[0])){c=this.options.values;f=arguments[0];for(e=0;e<c.length;e+=1){c[e]=this._trimAlignValue(f[e]);this._change(null,e)}this._refreshValue()}else return this.options.values&&this.options.values.length?this._values(b): 15788this.value();else return this._values()},_setOption:function(b,a){var c,f=0;if(d.isArray(this.options.values))f=this.options.values.length;d.Widget.prototype._setOption.apply(this,arguments);switch(b){case "disabled":if(a){this.handles.filter(".ui-state-focus").blur();this.handles.removeClass("ui-state-hover");this.handles.attr("disabled","disabled");this.element.addClass("ui-disabled")}else{this.handles.removeAttr("disabled");this.element.removeClass("ui-disabled")}break;case "orientation":this._detectOrientation(); 15789this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation);this._refreshValue();break;case "value":this._animateOff=true;this._refreshValue();this._change(null,0);this._animateOff=false;break;case "values":this._animateOff=true;this._refreshValue();for(c=0;c<f;c+=1)this._change(null,c);this._animateOff=false;break}},_value:function(){var b=this.options.value;return b=this._trimAlignValue(b)},_values:function(b){var a,c;if(arguments.length){a=this.options.values[b]; 15790return a=this._trimAlignValue(a)}else{a=this.options.values.slice();for(c=0;c<a.length;c+=1)a[c]=this._trimAlignValue(a[c]);return a}},_trimAlignValue:function(b){if(b<=this._valueMin())return this._valueMin();if(b>=this._valueMax())return this._valueMax();var a=this.options.step>0?this.options.step:1,c=(b-this._valueMin())%a;alignValue=b-c;if(Math.abs(c)*2>=a)alignValue+=c>0?a:-a;return parseFloat(alignValue.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max}, 15791_refreshValue:function(){var b=this.options.range,a=this.options,c=this,f=!this._animateOff?a.animate:false,e,j={},g,k,l,i;if(this.options.values&&this.options.values.length)this.handles.each(function(h){e=(c.values(h)-c._valueMin())/(c._valueMax()-c._valueMin())*100;j[c.orientation==="horizontal"?"left":"bottom"]=e+"%";d(this).stop(1,1)[f?"animate":"css"](j,a.animate);if(c.options.range===true)if(c.orientation==="horizontal"){if(h===0)c.range.stop(1,1)[f?"animate":"css"]({left:e+"%"},a.animate); 15792if(h===1)c.range[f?"animate":"css"]({width:e-g+"%"},{queue:false,duration:a.animate})}else{if(h===0)c.range.stop(1,1)[f?"animate":"css"]({bottom:e+"%"},a.animate);if(h===1)c.range[f?"animate":"css"]({height:e-g+"%"},{queue:false,duration:a.animate})}g=e});else{k=this.value();l=this._valueMin();i=this._valueMax();e=i!==l?(k-l)/(i-l)*100:0;j[c.orientation==="horizontal"?"left":"bottom"]=e+"%";this.handle.stop(1,1)[f?"animate":"css"](j,a.animate);if(b==="min"&&this.orientation==="horizontal")this.range.stop(1, 157931)[f?"animate":"css"]({width:e+"%"},a.animate);if(b==="max"&&this.orientation==="horizontal")this.range[f?"animate":"css"]({width:100-e+"%"},{queue:false,duration:a.animate});if(b==="min"&&this.orientation==="vertical")this.range.stop(1,1)[f?"animate":"css"]({height:e+"%"},a.animate);if(b==="max"&&this.orientation==="vertical")this.range[f?"animate":"css"]({height:100-e+"%"},{queue:false,duration:a.animate})}}});d.extend(d.ui.slider,{version:"1.8.14"})})(jQuery); 15794;/* 15795 * jQuery UI Tabs 1.8.14 15796 * 15797 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 15798 * Dual licensed under the MIT or GPL Version 2 licenses. 15799 * http://jquery.org/license 15800 * 15801 * http://docs.jquery.com/UI/Tabs 15802 * 15803 * Depends: 15804 * jquery.ui.core.js 15805 * jquery.ui.widget.js 15806 */ 15807(function(d,p){function u(){return++v}function w(){return++x}var v=0,x=0;d.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:false,cookie:null,collapsible:false,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"<div></div>",remove:null,select:null,show:null,spinner:"<em>Loading…</em>",tabTemplate:"<li><a href='#{href}'><span>#{label}</span></a></li>"},_create:function(){this._tabify(true)},_setOption:function(b,e){if(b=="selected")this.options.collapsible&& 15808e==this.options.selected||this.select(e);else{this.options[b]=e;this._tabify()}},_tabId:function(b){return b.title&&b.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+u()},_sanitizeSelector:function(b){return b.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+w());return d.cookie.apply(null,[b].concat(d.makeArray(arguments)))},_ui:function(b,e){return{tab:b,panel:e,index:this.anchors.index(b)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b= 15809d(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(b){function e(g,f){g.css("display","");!d.support.opacity&&f.opacity&&g[0].style.removeAttribute("filter")}var a=this,c=this.options,h=/^#.+/;this.list=this.element.find("ol,ul").eq(0);this.lis=d(" > li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return d("a",this)[0]});this.panels=d([]);this.anchors.each(function(g,f){var i=d(f).attr("href"),l=i.split("#")[0],q;if(l&&(l===location.toString().split("#")[0]|| 15810(q=d("base")[0])&&l===q.href)){i=f.hash;f.href=i}if(h.test(i))a.panels=a.panels.add(a.element.find(a._sanitizeSelector(i)));else if(i&&i!=="#"){d.data(f,"href.tabs",i);d.data(f,"load.tabs",i.replace(/#.*$/,""));i=a._tabId(f);f.href="#"+i;f=a.element.find("#"+i);if(!f.length){f=d(c.panelTemplate).attr("id",i).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(a.panels[g-1]||a.list);f.data("destroy.tabs",true)}a.panels=a.panels.add(f)}else c.disabled.push(g)});if(b){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"); 15811this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(c.selected===p){location.hash&&this.anchors.each(function(g,f){if(f.hash==location.hash){c.selected=g;return false}});if(typeof c.selected!=="number"&&c.cookie)c.selected=parseInt(a._cookie(),10);if(typeof c.selected!=="number"&&this.lis.filter(".ui-tabs-selected").length)c.selected= 15812this.lis.index(this.lis.filter(".ui-tabs-selected"));c.selected=c.selected||(this.lis.length?0:-1)}else if(c.selected===null)c.selected=-1;c.selected=c.selected>=0&&this.anchors[c.selected]||c.selected<0?c.selected:0;c.disabled=d.unique(c.disabled.concat(d.map(this.lis.filter(".ui-state-disabled"),function(g){return a.lis.index(g)}))).sort();d.inArray(c.selected,c.disabled)!=-1&&c.disabled.splice(d.inArray(c.selected,c.disabled),1);this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active"); 15813if(c.selected>=0&&this.anchors.length){a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash)).removeClass("ui-tabs-hide");this.lis.eq(c.selected).addClass("ui-tabs-selected ui-state-active");a.element.queue("tabs",function(){a._trigger("show",null,a._ui(a.anchors[c.selected],a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash))[0]))});this.load(c.selected)}d(window).bind("unload",function(){a.lis.add(a.anchors).unbind(".tabs");a.lis=a.anchors=a.panels=null})}else c.selected=this.lis.index(this.lis.filter(".ui-tabs-selected")); 15814this.element[c.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");c.cookie&&this._cookie(c.selected,c.cookie);b=0;for(var j;j=this.lis[b];b++)d(j)[d.inArray(b,c.disabled)!=-1&&!d(j).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");c.cache===false&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if(c.event!=="mouseover"){var k=function(g,f){f.is(":not(.ui-state-disabled)")&&f.addClass("ui-state-"+g)},n=function(g,f){f.removeClass("ui-state-"+ 15815g)};this.lis.bind("mouseover.tabs",function(){k("hover",d(this))});this.lis.bind("mouseout.tabs",function(){n("hover",d(this))});this.anchors.bind("focus.tabs",function(){k("focus",d(this).closest("li"))});this.anchors.bind("blur.tabs",function(){n("focus",d(this).closest("li"))})}var m,o;if(c.fx)if(d.isArray(c.fx)){m=c.fx[0];o=c.fx[1]}else m=o=c.fx;var r=o?function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.hide().removeClass("ui-tabs-hide").animate(o,o.duration||"normal", 15816function(){e(f,o);a._trigger("show",null,a._ui(g,f[0]))})}:function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.removeClass("ui-tabs-hide");a._trigger("show",null,a._ui(g,f[0]))},s=m?function(g,f){f.animate(m,m.duration||"normal",function(){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");e(f,m);a.element.dequeue("tabs")})}:function(g,f){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");a.element.dequeue("tabs")}; 15817this.anchors.bind(c.event+".tabs",function(){var g=this,f=d(g).closest("li"),i=a.panels.filter(":not(.ui-tabs-hide)"),l=a.element.find(a._sanitizeSelector(g.hash));if(f.hasClass("ui-tabs-selected")&&!c.collapsible||f.hasClass("ui-state-disabled")||f.hasClass("ui-state-processing")||a.panels.filter(":animated").length||a._trigger("select",null,a._ui(this,l[0]))===false){this.blur();return false}c.selected=a.anchors.index(this);a.abort();if(c.collapsible)if(f.hasClass("ui-tabs-selected")){c.selected= 15818-1;c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){s(g,i)}).dequeue("tabs");this.blur();return false}else if(!i.length){c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this));this.blur();return false}c.cookie&&a._cookie(c.selected,c.cookie);if(l.length){i.length&&a.element.queue("tabs",function(){s(g,i)});a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this))}else throw"jQuery UI Tabs: Mismatching fragment identifier."; 15819false&&this.blur()});this.anchors.bind("click.tabs",function(){return false})},_getIndex:function(b){if(typeof b=="string")b=this.anchors.index(this.anchors.filter("[href$="+b+"]"));return b},destroy:function(){var b=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var e= 15820d.data(this,"href.tabs");if(e)this.href=e;var a=d(this).unbind(".tabs");d.each(["href","load","cache"],function(c,h){a.removeData(h+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){d.data(this,"destroy.tabs")?d(this).remove():d(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")});b.cookie&&this._cookie(null,b.cookie);return this},add:function(b, 15821e,a){if(a===p)a=this.anchors.length;var c=this,h=this.options;e=d(h.tabTemplate.replace(/#\{href\}/g,b).replace(/#\{label\}/g,e));b=!b.indexOf("#")?b.replace("#",""):this._tabId(d("a",e)[0]);e.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var j=c.element.find("#"+b);j.length||(j=d(h.panelTemplate).attr("id",b).data("destroy.tabs",true));j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(a>=this.lis.length){e.appendTo(this.list);j.appendTo(this.list[0].parentNode)}else{e.insertBefore(this.lis[a]); 15822j.insertBefore(this.panels[a])}h.disabled=d.map(h.disabled,function(k){return k>=a?++k:k});this._tabify();if(this.anchors.length==1){h.selected=0;e.addClass("ui-tabs-selected ui-state-active");j.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){c._trigger("show",null,c._ui(c.anch
15822ors[0],c.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[a],this.panels[a]));return this},remove:function(b){b=this._getIndex(b);var e=this.options,a=this.lis.eq(b).remove(),c=this.panels.eq(b).remove(); 15823if(a.hasClass("ui-tabs-selected")&&this.anchors.length>1)this.select(b+(b+1<this.anchors.length?1:-1));e.disabled=d.map(d.grep(e.disabled,function(h){return h!=b}),function(h){return h>=b?--h:h});this._tabify();this._trigger("remove",null,this._ui(a.find("a")[0],c[0]));return this},enable:function(b){b=this._getIndex(b);var e=this.options;if(d.inArray(b,e.disabled)!=-1){this.lis.eq(b).removeClass("ui-state-disabled");e.disabled=d.grep(e.disabled,function(a){return a!=b});this._trigger("enable",null, 15824this._ui(this.anchors[b],this.panels[b]));return this}},disable:function(b){b=this._getIndex(b);var e=this.options;if(b!=e.selected){this.lis.eq(b).addClass("ui-state-disabled");e.disabled.push(b);e.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[b],this.panels[b]))}return this},select:function(b){b=this._getIndex(b);if(b==-1)if(this.options.collapsible&&this.options.selected!=-1)b=this.options.selected;else return this;this.anchors.eq(b).trigger(this.options.event+".tabs");return this}, 15825load:function(b){b=this._getIndex(b);var e=this,a=this.options,c=this.anchors.eq(b)[0],h=d.data(c,"load.tabs");this.abort();if(!h||this.element.queue("tabs").length!==0&&d.data(c,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(b).addClass("ui-state-processing");if(a.spinner){var j=d("span",c);j.data("label.tabs",j.html()).html(a.spinner)}this.xhr=d.ajax(d.extend({},a.ajaxOptions,{url:h,success:function(k,n){e.element.find(e._sanitizeSelector(c.hash)).html(k);e._cleanup();a.cache&&d.data(c, 15826"cache.tabs",true);e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.success(k,n)}catch(m){}},error:function(k,n){e._cleanup();e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.error(k,n,b,c)}catch(m){}}}));e.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]);this.panels.stop(false,true);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup();return this}, 15827url:function(b,e){this.anchors.eq(b).removeData("cache.tabs").data("load.tabs",e);return this},length:function(){return this.anchors.length}});d.extend(d.ui.tabs,{version:"1.8.14"});d.extend(d.ui.tabs.prototype,{rotation:null,rotate:function(b,e){var a=this,c=this.options,h=a._rotate||(a._rotate=function(j){clearTimeout(a.rotation);a.rotation=setTimeout(function(){var k=c.selected;a.select(++k<a.anchors.length?k:0)},b);j&&j.stopPropagation()});e=a._unrotate||(a._unrotate=!e?function(j){j.clientX&& 15828a.rotate(null)}:function(){t=c.selected;h()});if(b){this.element.bind("tabsshow",h);this.anchors.bind(c.event+".tabs",e);h()}else{clearTimeout(a.rotation);this.element.unbind("tabsshow",h);this.anchors.unbind(c.event+".tabs",e);delete this._rotate;delete this._unrotate}return this}})})(jQuery); 15829;/* 15830 * jQuery UI Datepicker 1.8.14 15831 * 15832 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 15833 * Dual licensed under the MIT or GPL Version 2 licenses. 15834 * http://jquery.org/license 15835 * 15836 * http://docs.jquery.com/UI/Datepicker 15837 * 15838 * Depends: 15839 * jquery.ui.core.js 15840 */ 15841(function(d,C){function M(){this.debug=false;this._curInst=null;this._keyEvent=false;this._disabledInputs=[];this._inDialog=this._datepickerShowing=false;this._mainDivId="ui-datepicker-div";this._inlineClass="ui-datepicker-inline";this._appendClass="ui-datepicker-append";this._triggerClass="ui-datepicker-trigger";this._dialogClass="ui-datepicker-dialog";this._disableClass="ui-datepicker-disabled";this._unselectableClass="ui-datepicker-unselectable";this._currentClass="ui-datepicker-current-day";this._dayOverClass= 15842"ui-datepicker-days-cell-over";this.regional=[];this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Frid
15842ay","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su", 15843"Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:false,showMonthAfterYear:false,yearSuffix:""};this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:false,hideIfNoPrevNext:false,navigationAsDateFormat:false,gotoCurrent:false,changeMonth:false,changeYear:false,yearRange:"c-10:c+10",showOtherMonths:false,selectOtherMonths:false,showWeek:false,calculateWeek:this.iso8601Week,shortYearCutoff:"+10", 15844minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:true,showButtonPanel:false,autoSize:false};d.extend(this._defaults,this.regional[""]);this.dpDiv=N(d('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}function N(a){return a.bind("mouseout",function(b){b= 15845d(b.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");b.length&&b.removeClass("ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover")}).bind("mouseover",function(b){b=d(b.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");if(!(d.datepicker._isDisabledDatepicker(J.inline?a.parent()[0]:J.input[0])||!b.length)){b.parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");b.addClass("ui-state-hover"); 15846b.hasClass("ui-datepicker-prev")&&b.addClass("ui-datepicker-prev-hover");b.hasClass("ui-datepicker-next")&&b.addClass("ui-datepicker-next-hover")}})}function H(a,b){d.extend(a,b);for(var c in b)if(b[c]==null||b[c]==C)a[c]=b[c];return a}d.extend(d.ui,{datepicker:{version:"1.8.14"}});var A=(new Date).getTime(),J;d.extend(M.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(a){H(this._defaults, 15847a||{});return this},_attachDatepicker:function(a,b){var c=null;for(var e in this._defaults){var f=a.getAttribute("date:"+e);if(f){c=c||{};try{c[e]=eval(f)}catch(h){c[e]=f}}}e=a.nodeName.toLowerCase();f=e=="div"||e=="span";if(!a.id){this.uuid+=1;a.id="dp"+this.uuid}var i=this._newInst(d(a),f);i.settings=d.extend({},b||{},c||{});if(e=="input")this._connectDatepicker(a,i);else f&&this._inlineDatepicker(a,i)},_newInst:function(a,b){return{id:a[0].id.replace(/([^A-Za-z0-9_-])/g,"\\\\$1"),input:a,selectedDay:0, 15848selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:!b?this.dpDiv:N(d('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}},_connectDatepicker:function(a,b){var c=d(a);b.append=d([]);b.trigger=d([]);if(!c.hasClass(this.markerClassName)){this._attachments(c,b);c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(e,f,h){b.settings[f]= 15849h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});this._autoSize(b);d.data(a,"datepicker",b)}},_attachments:function(a,b){var c=this._get(b,"appendText"),e=this._get(b,"isRTL");b.append&&b.append.remove();if(c){b.append=d('<span class="'+this._appendClass+'">'+c+"</span>");a[e?"before":"after"](b.append)}a.unbind("focus",this._showDatepicker);b.trigger&&b.trigger.remove();c=this._get(b,"showOn");if(c=="focus"||c=="both")a.focus(this._showDatepicker);if(c=="button"||c=="both"){c= 15850this._get(b,"buttonText");var f=this._get(b,"buttonImage");b.trigger=d(this._get(b,"buttonImageOnly")?d("<img/>").addClass(this._triggerClass).attr({src:f,alt:c,title:c}):d('<button type="button"></button>').addClass(this._triggerClass).html(f==""?c:d("<img/>").attr({src:f,alt:c,title:c})));a[e?"before":"after"](b.trigger);b.trigger.click(function(){d.datepicker._datepickerShowing&&d.datepicker._lastInput==a[0]?d.datepicker._hideDatepicker():d.datepicker._showDatepicker(a[0]);return false})}}
15850,_autoSize:function(a){if(this._get(a, 15851"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var e=function(f){for(var h=0,i=0,g=0;g<f.length;g++)if(f[g].length>h){h=f[g].length;i=g}return i};b.setMonth(e(this._get(a,c.match(/MM/)?"monthNames":"monthNamesShort")));b.setDate(e(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a,b){var c=d(a);if(!c.hasClass(this.markerClassName)){c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker", 15852function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});d.data(a,"datepicker",b);this._setDate(b,this._getDefaultDate(b),true);this._updateDatepicker(b);this._updateAlternate(b);b.dpDiv.show()}},_dialogDatepicker:function(a,b,c,e,f){a=this._dialogInst;if(!a){this.uuid+=1;this._dialogInput=d('<input type="text" id="'+("dp"+this.uuid)+'" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');this._dialogInput.keydown(this._doKeyDown);d("body").append(this._dialogInput); 15853a=this._dialogInst=this._newInst(this._dialogInput,false);a.settings={};d.data(this._dialogInput[0],"datepicker",a)}H(a.settings,e||{});b=b&&b.constructor==Date?this._formatDate(a,b):b;this._dialogInput.val(b);this._pos=f?f.length?f:[f.pageX,f.pageY]:null;if(!this._pos)this._pos=[document.documentElement.clientWidth/2-100+(document.documentElement.scrollLeft||document.body.scrollLeft),document.documentElement.clientHeight/2-150+(document.documentElement.scrollTop||document.body.scrollTop)];this._dialogInput.css("left", 15854this._pos[0]+20+"px").css("top",this._pos[1]+"px");a.settings.onSelect=c;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);d.blockUI&&d.blockUI(this.dpDiv);d.data(this._dialogInput[0],"datepicker",a);return this},_destroyDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();d.removeData(a,"datepicker");if(e=="input"){c.append.remove();c.trigger.remove();b.removeClass(this.markerClassName).unbind("focus", 15855this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)}else if(e=="div"||e=="span")b.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=false;c.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else if(e=="div"||e=="span"){b= 15856b.children("."+this._inlineClass);b.children().removeClass("ui-state-disabled");b.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled")}this._disabledInputs=d.map(this._disabledInputs,function(f){return f==a?null:f})}},_disableDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=true;c.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5", 15857cursor:"default"})}else if(e=="div"||e=="span"){b=b.children("."+this._inlineClass);b.children().addClass("ui-state-disabled");b.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled")}this._disabledInputs=d.map(this._disabledInputs,function(f){return f==a?null:f});this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(a){if(!a)return false;for(var b=0;b<this._disabledInputs.length;b++)if(this._disabledInputs[b]==a)return true;return false}, 15858_getInst:function(a){try{return d.data(a,"datepicker")}catch(b){throw"Missing instance data for this datepicker";}},_optionDatepicker:function(a,b,c){var e=this._getInst(a);if(arguments.length==2&&typeof b=="string")return b=="defaults"?d.extend({},d.datepicker._defaults):e?b=="all"?d.extend({},e.settings):this._get(e,b):null;var f=b||{};if(typeof b=="string"){f={};f[b]=c}if(e){this._curInst==e&&this._hideDatepicker();var h=this._getDateDatepicker(a,true),i=this._getMinMaxDate(e,"min"),g=this._getMinMaxDate(e, 15859"max");H(e.settings,f);if(i!==null&&f.dateFormat!==C&&f.minDate===C)e.settings.minDate=this._formatDate(e,i);if(g!==null&&f.dateFormat!==C&&f.maxDate===C)e.settings.maxDate=this._formatDate(e,g);this._attachments(d(a),e);this._autoSize(e);this._setDate(e,h);this._updateAlternate(e);this._updateDatepicker(e)}},_changeDatepicker:function(a,b,c){this._optionDatepicker(a,b,c)},_refreshDatepicker:function(a){(a=this._getInst(a))&&this._updateDatepicker(a)},_setDateDatepicker:function(a,b){if(a=this._getInst(a)){this._setDate(a, 15860b);this._updateDatepicker(a);
15860this._updateAlternate(a)}},_getDateDatepicker:function(a,b){(a=this._getInst(a))&&!a.inline&&this._setDateFromField(a,b);return a?this._getDate(a):null},_doKeyDown:function(a){var b=d.datepicker._getInst(a.target),c=true,e=b.dpDiv.is(".ui-datepicker-rtl");b._keyEvent=true;if(d.datepicker._datepickerShowing)switch(a.keyCode){case 9:d.datepicker._hideDatepicker();c=false;break;case 13:c=d("td."+d.datepicker._dayOverClass+":not(."+d.datepicker._currentClass+")",b.dpDiv); 15861c[0]?d.datepicker._selectDay(a.target,b.selectedMonth,b.selectedYear,c[0]):d.datepicker._hideDatepicker();return false;case 27:d.datepicker._hideDatepicker();break;case 33:d.datepicker._adjustDate(a.target,a.ctrlKey?-d.datepicker._get(b,"stepBigMonths"):-d.datepicker._get(b,"stepMonths"),"M");break;case 34:d.datepicker._adjustDate(a.target,a.ctrlKey?+d.datepicker._get(b,"stepBigMonths"):+d.datepicker._get(b,"stepMonths"),"M");break;case 35:if(a.ctrlKey||a.metaKey)d.datepicker._clearDate(a.target); 15862c=a.ctrlKey||a.metaKey;break;case 36:if(a.ctrlKey||a.metaKey)d.datepicker._gotoToday(a.target);c=a.ctrlKey||a.metaKey;break;case 37:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,e?+1:-1,"D");c=a.ctrlKey||a.metaKey;if(a.originalEvent.altKey)d.datepicker._adjustDate(a.target,a.ctrlKey?-d.datepicker._get(b,"stepBigMonths"):-d.datepicker._get(b,"stepMonths"),"M");break;case 38:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,-7,"D");c=a.ctrlKey||a.metaKey;break;case 39:if(a.ctrlKey|| 15863a.metaKey)d.datepicker._adjustDate(a.target,e?-1:+1,"D");c=a.ctrlKey||a.metaKey;if(a.originalEvent.altKey)d.datepicker._adjustDate(a.target,a.ctrlKey?+d.datepicker._get(b,"stepBigMonths"):+d.datepicker._get(b,"stepMonths"),"M");break;case 40:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,+7,"D");c=a.ctrlKey||a.metaKey;break;default:c=false}else if(a.keyCode==36&&a.ctrlKey)d.datepicker._showDatepicker(this);else c=false;if(c){a.preventDefault();a.stopPropagation()}},_doKeyPress:function(a){var b= 15864d.datepicker._getInst(a.target);if(d.datepicker._get(b,"constrainInput")){b=d.datepicker._possibleChars(d.datepicker._get(b,"dateFormat"));var c=String.fromCharCode(a.charCode==C?a.keyCode:a.charCode);return a.ctrlKey||a.metaKey||c<" "||!b||b.indexOf(c)>-1}},_doKeyUp:function(a){a=d.datepicker._getInst(a.target);if(a.input.val()!=a.lastVal)try{if(d.datepicker.parseDate(d.datepicker._get(a,"dateFormat"),a.input?a.input.val():null,d.datepicker._getFormatConfig(a))){d.datepicker._setDateFromField(a); 15865d.datepicker._updateAlternate(a);d.datepicker._updateDatepicker(a)}}catch(b){d.datepicker.log(b)}return true},_showDatepicker:function(a){a=a.target||a;if(a.nodeName.toLowerCase()!="input")a=d("input",a.parentNode)[0];if(!(d.datepicker._isDisabledDatepicker(a)||d.datepicker._lastInput==a)){var b=d.datepicker._getInst(a);if(d.datepicker._curInst&&d.datepicker._curInst!=b){d.datepicker._datepickerShowing&&d.datepicker._triggerOnClose(d.datepicker._curInst);d.datepicker._curInst.dpDiv.stop(true,true)}var c= 15866d.datepicker._get(b,"beforeShow");H(b.settings,c?c.apply(a,[a,b]):{});b.lastVal=null;d.datepicker._lastInput=a;d.datepicker._setDateFromField(b);if(d.datepicker._inDialog)a.value="";if(!d.datepicker._pos){d.datepicker._pos=d.datepicker._findPos(a);d.datepicker._pos[1]+=a.offsetHeight}var e=false;d(a).parents().each(function(){e|=d(this).css("position")=="fixed";return!e});if(e&&false){d.datepicker._pos[0]-=document.documentElement.scrollLeft;d.datepicker._pos[1]-=document.documentElement.scrollTop}c= 15867{left:d.datepicker._pos[0],top:d.datepicker._pos[1]};d.datepicker._pos=null;b.dpDiv.empty();b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});d.datepicker._updateDatepicker(b);c=d.datepicker._checkOffset(b,c,e);b.dpDiv.css({position:d.datepicker._inDialog&&d.blockUI?"static":e?"fixed":"absolute",display:"none",left:c.left+"px",top:c.top+"px"});if(!b.inline){c=d.datepicker._get(b,"showAnim");var f=d.datepicker._get(b,"duration"),h=function(){var i=b.dpDiv.find("iframe.ui-datepicker-cover"); 15868if(i.length){var g=d.datepicker._getBorders(b.dpDiv);i.css({left:-g[0],top:-g[1],width:b.dpDiv.outerWidth(false),height:b.dpDiv.outerHeight(false)})}};b.dpDiv.zIndex(d(a).zIndex()+1);d.datepicker._datepickerShowing=true;d.effects&&d.effects[c]?b.dpDiv.show(c,d.datepicker._get(b,"showOptions"),f,h):b.dpDiv[c||"show"](c?f:null,h);if(!c||!f)h();b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus();d.datepicker._curInst=b}}},_updateDatepicker:function(a){this.maxRows=4;var b=d.datepicker._getBorders(a.dpDiv); 15869J=a;a.dpDiv.empty().append(this._generateHTML(a));var c=a.dpDiv.find("iframe.ui-datepicker-cover");c.length&&c.css({left:-b[0],top:-b[1],width:a.dpDiv.outerWidth(false),height:a.dpDiv.outerHeight(false)});a.dpDiv.find("."+this._dayOverClass+" a").mouseover();b=this._getNumberOfMonths(a);c=b[1];a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");c>1&&a.dpDiv.addClass("ui-datepicker-multi-"+c).css("width",17*c+"em");a.dpDiv[(b[0]!=1||b[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi"); 15870a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");a==d.datepicker._curInst&&d.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&&!a.input.is(":disabled")&&a.input[0]!=document.activeElement&&a.input.focus();if(a.yearshtml){var e=a.yearshtml;setTimeout(function(){e===a.yearshtml&&a.yearshtml&&a.dpDiv.find("select.ui-datepicker-year:first").replaceWith(a.yearshtml);e=a.yearshtml=null},0)}},_getBorders:function(a){var b=function(c){return{thin:1,medium:2,thick:3}[c]|| 15871c};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,b,c){var e=a.dpDiv.outerWidth(false),f=a.dpDiv.outerHeight(false),h=a.input?a.input.outerWidth(false):0,i=a.input?a.input.outerHeight(false):0,g=document.documentElement.clientWidth+d(document).scrollLeft(),j=document.documentElement.clientHeight+d(document).scrollTop();b.left-=this._get(a,"isRTL")?e-h:0;b.left-=c&&b.left==a.input.offset().left?d(document).scrollLeft():0;b.top-=c&&b.top==a.input.offset().top+ 15872i?d(document).scrollTop():0;b.left-=Math.min(b.left,b.left+e>g&&g>e?Math.abs(b.left+e-g):0);b.top-=Math.min(b.top,b.top+f>j&&j>f?Math.abs(f+i):0);return b},_findPos:function(a){for(var b=this._get(this._getInst(a),"isRTL");a&&(a.type=="hidden"||a.nodeType!=1||d.expr.filters.hidden(a));)a=a[b?"previousSibling":"nextSibling"];a=d(a).offset();return[a.left,a.top]},_triggerOnClose:function(a){var b=this._get(a,"onClose");if(b)b.apply(a.input?a.input[0]:null,[a.input?a.input.val():"",a])},_hideDatepicker:function(a){var b= 15873this._curInst;if(!(!b||a&&b!=d.data(a,"datepicker")))if(this._datepickerShowing){a=this._get(b,"showAnim");var c=this._get(b,"duration"),e=function(){d.datepicker._tidyDialog(b);this._curInst=null};d.effects&&d.effects[a]?b.dpDiv.hide(a,d.datepicker._get(b,"showOptions"),c,e):b.dpDiv[a=="slideDown"?"slideUp":a=="fadeIn"?"fadeOut":"hide"](a?c:null,e);a||e();d.datepicker._triggerOnClose(b);this._datepickerShowing=false;this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",
15874left:"0",top:"-100px"});if(d.blockUI){d.unblockUI();d("body").append(this.dpDiv)}}this._inDialog=false}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(a){if(d.datepicker._curInst){a=d(a.target);a[0].id!=d.datepicker._mainDivId&&a.parents("#"+d.datepicker._mainDivId).length==0&&!a.hasClass(d.datepicker.markerClassName)&&!a.hasClass(d.datepicker._triggerClass)&&d.datepicker._datepickerShowing&&!(d.datepicker._inDialog&& 15875d.blockUI)&&d.datepicker._hideDatepicker()}},_adjustDate:function(a,b,c){a=d(a);var e=this._getInst(a[0]);if(!this._isDisabledDatepicker(a[0])){this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"):0),c);this._updateDatepicker(e)}},_gotoToday:function(a){a=d(a);var b=this._getInst(a[0]);if(this._get(b,"gotoCurrent")&&b.currentDay){b.selectedDay=b.currentDay;b.drawMonth=b.selectedMonth=b.currentMonth;b.drawYear=b.selectedYear=b.currentYear}else{var c=new Date;b.selectedDay=c.getDate();b.drawMonth= 15876b.selectedMonth=c.getMonth();b.drawYear=b.selectedYear=c.getFullYear()}this._notifyChange(b);this._adjustDate(a)},_selectMonthYear:function(a,b,c){a=d(a);var e=this._getInst(a[0]);e._selectingMonthYear=false;e["selected"+(c=="M"?"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10);this._notifyChange(e);this._adjustDate(a)},_clickMonthYear:function(a){var b=this._getInst(d(a)[0]);b.input&&b._selectingMonthYear&&setTimeout(function(){b.input.focus()},0);b._selectingMonthYear= 15877!b._selectingMonthYear},_selectDay:function(a,b,c,e){var f=d(a);if(!(d(e).hasClass(this._unselectableClass)||this._isDisabledDatepicker(f[0]))){f=this._getInst(f[0]);f.selectedDay=f.currentDay=d("a",e).html();f.selectedMonth=f.currentMonth=b;f.selectedYear=f.currentYear=c;this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))}},_clearDate:function(a){a=d(a);this._getInst(a[0]);this._selectDate(a,"")},_selectDate:function(a,b){a=this._getInst(d(a)[0]);b=b!=null?b:this._formatDate(a); 15878a.input&&a.input.val(b);this._updateAlternate(a);var c=this._get(a,"onSelect");if(c)c.apply(a.input?a.input[0]:null,[b,a]);else a.input&&a.input.trigger("change");if(a.inline)this._updateDatepicker(a);else{this._hideDatepicker();this._lastInput=a.input[0];typeof a.input[0]!="object"&&a.input.focus();this._lastInput=null}},_updateAlternate:function(a){var b=this._get(a,"altField");if(b){var c=this._get(a,"altFormat")||this._get(a,"dateFormat"),e=this._getDate(a),f=this.formatDate(c,e,this._getFormatConfig(a)); 15879d(b).each(function(){d(this).val(f)})}},noWeekends:function(a){a=a.getDay();return[a>0&&a<6,""]},iso8601Week:function(a){a=new Date(a.getTime());a.setDate(a.getDate()+4-(a.getDay()||7));var b=a.getTime();a.setMonth(0);a.setDate(1);return Math.floor(Math.round((b-a)/864E5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b=="object"?b.toString():b+"";if(b=="")return null;var e=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff;e=typeof e!="string"?e:(new Date).getFullYear()% 15880100+parseInt(e,10);for(var f=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,h=(c?c.dayNames:null)||this._defaults.dayNames,i=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c?c.monthNames:null)||this._defaults.monthNames,j=c=-1,l=-1,u=-1,k=false,o=function(p){(p=B+1<a.length&&a.charAt(B+1)==p)&&B++;return p},m=function(p){var D=o(p);p=new RegExp("^\\d{1,"+(p=="@"?14:p=="!"?20:p=="y"&&D?4:p=="o"?3:2)+"}");p=b.substring(q).match(p);if(!p)throw"Missing number at position "+q;q+= 15881p[0].length;return parseInt(p[0],10)},n=function(p,D,K){p=d.map(o(p)?K:D,function(w,x){return[[x,w]]}).sort(function(w,x){return-(w[1].length-x[1].length)});var E=-1;d.each(p,function(w,x){w=x[1];if(b.substr(q,w.length).toLowerCase()==w.toLowerCase()){E=x[0];q+=w.length;return false}});if(E!=-1)return E+1;else throw"Unknown name at position "+q;},s=function(){if(b.charAt(q)!=a.charAt(B))throw"Unexpected literal at position "+q;q++},q=0,B=0;B<a.length;B++)if(k)if(a.charAt(B)=="'"&&!o("'"))k=false; 15882else s();else switch(a.charAt(B)){case "d":l=m("d");break;case "D":n("D",f,h);break;case "o":u=m("o");break;case "m":j=m("m");break;case "M":j=n("M",i,g);break;case "y":c=m("y");break;case "@":var v=new Date(m("@"));c=v.getFullYear();j=v.getMonth()+1;l=v.getDate();break;case "!":v=new Date((m("!")-this._ticksTo1970)/1E4);c=v.getFullYear();j=v.getMonth()+1;l=v.getDate();break;
15882case "'":if(o("'"))s();else k=true;break;default:s()}if(q<b.length)throw"Extra/unparsed characters found in date: "+b.substring(q); 15883if(c==-1)c=(new Date).getFullYear();else if(c<100)c+=(new Date).getFullYear()-(new Date).getFullYear()%100+(c<=e?0:-100);if(u>-1){j=1;l=u;do{e=this._getDaysInMonth(c,j-1);if(l<=e)break;j++;l-=e}while(1)}v=this._daylightSavingAdjust(new Date(c,j-1,l));if(v.getFullYear()!=c||v.getMonth()+1!=j||v.getDate()!=l)throw"Invalid date";return v},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y", 15884TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1E7,formatDate:function(a,b,c){if(!b)return"";var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,h=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort;c=(c?c.monthNames:null)||this._defaults.monthNames;var i=function(o){(o=k+1<a.length&&a.charAt(k+1)==o)&&k++;return o},g=function(o,m,n){m=""+m;if(i(o))for(;m.length< 15885n;)m="0"+m;return m},j=function(o,m,n,s){return i(o)?s[m]:n[m]},l="",u=false;if(b)for(var k=0;k<a.length;k++)if(u)if(a.charAt(k)=="'"&&!i("'"))u=false;else l+=a.charAt(k);else switch(a.charAt(k)){case "d":l+=g("d",b.getDate(),2);break;case "D":l+=j("D",b.getDay(),e,f);break;case "o":l+=g("o",Math.round(((new Date(b.getFullYear(),b.getMonth(),b.getDate())).getTime()-(new Date(b.getFullYear(),0,0)).getTime())/864E5),3);break;case "m":l+=g("m",b.getMonth()+1,2);break;case "M":l+=j("M",b.getMonth(),h, 15886c);break;case "y":l+=i("y")?b.getFullYear():(b.getYear()%100<10?"0":"")+b.getYear()%100;break;case "@":l+=b.getTime();break;case "!":l+=b.getTime()*1E4+this._ticksTo1970;break;
15886case "'":if(i("'"))l+="'";else u=true;break;default:l+=a.charAt(k)}return l},_possibleChars:function(a){for(var b="",c=false,e=function(h){(h=f+1<a.length&&a.charAt(f+1)==h)&&f++;return h},f=0;f<a.length;f++)if(c)if(a.charAt(f)=="'"&&!e("'"))c=false;else b+=a.charAt(f);else switch(a.charAt(f)){case "d":case "m":case "y":case "@":b+= 15887"0123456789";break;case "D":case "M":return null;case "'":if(e("'"))b+="'";else c=true;break;default:b+=a.charAt(f)}return b},_get:function(a,b){return a.settings[b]!==C?a.settings[b]:this._defaults[b]},_setDateFromField:function(a,b){if(a.input.val()!=a.lastVal){var c=this._get(a,"dateFormat"),e=a.lastVal=a.input?a.input.val():null,f,h;f=h=this._getDefaultDate(a);var i=this._getFormatConfig(a);try{f=this.parseDate(c,e,i)||h}catch(g){this.log(g);e=b?"":e}a.selectedDay=f.getDate();a.drawMonth=a.selectedMonth= 15888f.getMonth();a.drawYear=a.selectedYear=f.getFullYear();a.currentDay=e?f.getDate():0;a.currentMonth=e?f.getMonth():0;a.currentYear=e?f.getFullYear():0;this._adjustInstDate(a)}},_getDefaultDate:function(a){return this._restrictMinMax(a,this._determineDate(a,this._get(a,"defaultDate"),new Date))},_determineDate:function(a,b,c){var e=function(h){var i=new Date;i.setDate(i.getDate()+h);return i},f=function(h){try{return d.datepicker.parseDate(d.datepicker._get(a,"dateFormat"),h,d.datepicker._getFormatConfig(a))}catch(i){}var g= 15889(h.toLowerCase().match(/^c/)?d.datepicker._getDate(a):null)||new Date,j=g.getFullYear(),l=g.getMonth();g=g.getDate();for(var u=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,k=u.exec(h);k;){switch(k[2]||"d"){case "d":case "D":g+=parseInt(k[1],10);break;case "w":case "W":g+=parseInt(k[1],10)*7;break;case "m":case "M":l+=parseInt(k[1],10);g=Math.min(g,d.datepicker._getDaysInMonth(j,l));break;case "y":case "Y":j+=parseInt(k[1],10);g=Math.min(g,d.datepicker._getDaysInMonth(j,l));break}k=u.exec(h)}return new Date(j, 15890l,g)};if(b=(b=b==null||b===""?c:typeof b=="string"?f(b):typeof b=="number"?isNaN(b)?c:e(b):new Date(b.getTime()))&&b.toString()=="Invalid Date"?c:b){b.setHours(0);b.setMinutes(0);b.setSeconds(0);b.setMilliseconds(0)}return this._daylightSavingAdjust(b)},_daylightSavingAdjust:function(a){if(!a)return null;a.setHours(a.getHours()>12?a.getHours()+2:0);return a},_setDate:function(a,b,c){var e=!b,f=a.selectedMonth,h=a.selectedYear;b=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay= 15891a.currentDay=b.getDate();a.drawMonth=a.selectedMonth=a.currentMonth=b.getMonth();a.drawYear=a.selectedYear=a.currentYear=b.getFullYear();if((f!=a.selectedMonth||h!=a.selectedYear)&&!c)this._notifyChange(a);this._adjustInstDate(a);if(a.input)a.input.val(e?"":this._formatDate(a))},_getDate:function(a){return!a.currentYear||a.input&&a.input.val()==""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay))},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(), 15892b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),e=this._get(a,"showButtonPanel"),f=this._get(a,"hideIfNoPrevNext"),h=this._get(a,"navigationAsDateFormat"),i=this._getNumberOfMonths(a),g=this._get(a,"showCurrentAtPos"),j=this._get(a,"stepMonths"),l=i[0]!=1||i[1]!=1,u=this._daylightSavingAdjust(!a.currentDay?new Date(9999,9,9):new Date(a.currentYear,a.currentMonth,a.currentDay)),k=this._getMinMaxDate(a,"min"),o=this._getMinMaxDate(a,"max");g=a.drawMonth-g;var m=a.drawYear;if(g<0){g+=12;m--}if(o){var n= 15893this._daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth()-i[0]*i[1]+1,o.getDate()));for(n=k&&n<k?k:n;this._daylightSavingAdjust(new Date(m,g,1))>n;){g--;if(g<0){g=11;m--}}}a.drawMonth=g;a.drawYear=m;n=this._get(a,"prevText");n=!h?n:this.formatDate(n,this._daylightSavingAdjust(new Date(m,g-j,1)),this._getFormatConfig(a));n=this._canAdjustMonth(a,-1,m,g)?'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_'+A+".datepicker._adjustDate('#"+a.id+"', -"+j+", 'M');\" title=\""+n+'"><span class="ui-icon ui-icon-circle-triangle-'+ 15894(c?"e":"w")+'">'+n+"</span></a>":f?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+n+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+n+"</span></a>";var s=this._get(a,"nextText");s=!h?s:this.formatDate(s,this._daylightSavingAdjust(new Date(m,g+j,1)),this._getFormatConfig(a));f=this._canAdjustMonth(a,+1,m,g)?'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_'+A+".datepicker._adjustDate('#"+a.id+"', +"+j+", 'M');\" title=\""+s+'"><span class="ui-icon ui-icon-circle-triangle-'+ 15895(c?"w":"e")+'">'+s+"</span></a>":f?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+s+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+s+"</span></a>";j=this._get(a,"currentText");s=this._get(a,"gotoCurrent")&&a.currentDay?u:b;j=!h?j:this.formatDate(j,s,this._getFormatConfig(a));h=!a.inline?'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_'+A+'.datepicker._hideDatepicker();">'+this._get(a, 15896"closeText")+"</button>":"";e=e?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(c?h:"")+(this._isInRange(a,s)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_'+A+".datepicker._gotoToday('#"+a.id+"');\">"+j+"</button>":"")+(c?"":h)+"</div>":"";h=parseInt(this._get(a,"firstDay"),10);h=isNaN(h)?0:h;j=this._get(a,"showWeek");s=this._get(a,"dayNames");this._get(a,"dayNamesShort");var q=this._get(a,"dayNamesMin"),B= 15897this._get(a,"monthNames"),v=this._get(a,"monthNamesShort"),p=this._get(a,"beforeShowDay"),D=this._get(a,"showOtherMonths"),K=this._get(a,"selectOtherMonths");this._get(a,"calculateWeek");for(var E=this._getDefaultDate(a),w="",x=0;x<i[0];x++){var O="";this.maxRows=4;for(var G=0;G<i[1];G++){var P=this._daylightSavingAdjust(new Date(m,g,a.selectedDay)),t=" ui-corner-all",y="";if(l){y+='<div class="ui-datepicker-group';if(i[1]>1)switch(G){case 0:y+=" ui-datepicker-group-first";t=" ui-corner-"+(c?"right": 15898"left");break;case i[1]-1:y+=" ui-datepicker-group-last";t=" ui-corner-"+(c?"left":"right");break;default:y+=" ui-datepicker-group-middle";t="";break}y+='">'}y+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+t+'">'+(/all|left/.test(t)&&x==0?c?f:n:"")+(/all|right/.test(t)&&x==0?c?n:f:"")+this._generateMonthYearHeader(a,g,m,k,o,x>0||G>0,B,v)+'</div><table class="ui-datepicker-calendar"><thead><tr>';var z=j?'<th class="ui-datepicker-week-col">'+this._get(a,"weekHeader")+"</th>": 15899"";for(t=0;t<7;t++){var r=(t+h)%7;z+="<th"+((t+h+6)%7>=5?' class="ui-datepicker-week-end"':"")+'><span title="'+s[r]+'">'+q[r]+"</span></th>"}y+=z+"</tr></thead><tbody>";z=this._getDaysInMonth(m,g);if(m==a.selectedYear&&g==a.selectedMonth)a.selectedDay=Math.min(a.selectedDay,z);t=(this._getFirstDayOfMonth(m,g)-h+7)%7;z=Math.ceil((t+z)/7);this.maxRows=z=l?this.maxRows>z?this.maxRows:z:z;r=this._daylightSavingAdjust(new Date(m,g,1-t));for(var Q=0;Q<z;Q++){y+="<tr>";var R=!j?"":'<td class="ui-datepicker-week-col">'+ 15900this._get(a,"calculateWeek")(r)+"</td>";for(t=0;t<7;t++){var I=p?p.apply(a.input?a.input[0]:null,[r]):[true,""],F=r.getMonth()!=g,L=F&&!K||!I[0]||k&&r<k||o&&r>o;R+='<td class="'+((t+h+6)%7>=5?" ui-datepicker-week-end":"")+(F?" ui-datepicker-other-month":"")+(r.getTime()==P.getTime()&&g==a.selectedMonth&&a._keyEvent||E.getTime()==r.getTime()&&E.getTime()==P.getTime()?" "+this._dayOverClass:"")+(L?" "+this._unselectableClass+" ui-state-disabled":"")+(F&&!D?"":" "+I[1]+(r.getTime()==u.getTime()?" "+ 15901this._currentClass:"")+(r.getTime()==b.getTime()?" ui-datepicker-today":""))+'"'+((!F||D)&&I[2]?' title="'+I[2]+'"':"")+(L?"":' onclick="DP_jQuery_'+A+".datepicker._selectDay('#"+a.id+"',"+r.getMonth()+","+r.getFullYear()+', this);return false;"')+">"+(F&&!D?" ":L?'<span class="ui-state-default">'+r.getDate()+"</span>":'<a class="ui-state-default'+(r.getTime()==b.getTime()?" ui-state-highlight":"")+(r.getTime()==u.getTime()?" ui-state-active":"")+(F?" ui-priority-secondary":"")+'" href="#">'+ 15902r.getDate()+"</a>")+"</td>";r.setDate(r.getDate()+1);r=this._daylightSavingAdjust(r)}y+=R+"</tr>"}g++;if(g>11){g=0;m++}y+="</tbody></table>"+(l?"</div>"+(i[0]>0&&G==i[1]-1?'<div class="ui-datepicker-row-break"></div>':""):"");O+=y}w+=O}w+=e+(false&&!a.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':"");a._keyEvent=false;return w},_generateMonthYearHeader:function(a,b,c,e,f,h,i,g){var j=this._get(a,"changeMonth"), 15903l=this._get(a,"changeYear"),u=this._get(a,"showMonthAfterYear"),k='<div class="ui-datepicker-title">',o="";if(h||!j)o+='<span class="ui-datepicker-month">'+i[b]+"</span>";else{i=e&&e.getFullYear()==c;var m=f&&f.getFullYear()==c;o+='<select class="ui-datepicker-month" onchange="DP_jQuery_'+A+".datepicker._selectMonthYear('#"+a.id+"', this, 'M');\" onclick=\"DP_jQuery_"+A+".datepicker._clickMonthYear('#"+a.id+"');\">";for(var n=0;n<12;n++)if((!i||n>=e.getMonth())&&(!m||n<=f.getMonth()))o+='<option value="'+ 15904n+'"'+(n==b?' selected="selected"':"")+">"+g[n]+"</option>";o+="</select>"}u||(k+=o+(h||!(j&&l)?" ":""));if(!a.yearshtml){a.yearshtml="";if(h||!l)k+='<span class="ui-datepicker-year">'+c+"</span>";else{g=this._get(a,"yearRange").split(":");var s=(new Date).getFullYear();i=function(q){q=q.match(/c[+-].*/)?c+parseInt(q.substring(1),10):q.match(/[+-].*/)?s+parseInt(q,10):parseInt(q,10);return isNaN(q)?s:q};b=i(g[0]);g=Math.max(b,i(g[1]||""));b=e?Math.max(b,e.getFullYear()):b;g=f?Math.min(g,f.getFullYear()): 15905g;
15905for(a.yearshtml+='<select class="ui-datepicker-year" onchange="DP_jQuery_'+A+".datepicker._selectMonthYear('#"+a.id+"', this, 'Y');\" onclick=\"DP_jQuery_"+A+".datepicker._clickMonthYear('#"+a.id+"');\">";b<=g;b++)a.yearshtml+='<option value="'+b+'"'+(b==c?' selected="selected"':"")+">"+b+"</option>";a.yearshtml+="</select>";k+=a.yearshtml;a.yearshtml=null}}k+=this._get(a,"yearSuffix");if(u)k+=(h||!(j&&l)?" ":"")+o;k+="</div>";return k},_adjustInstDate:function(a,b,c){var e=a.drawYear+(c== 15906"Y"?b:0),f=a.drawMonth+(c=="M"?b:0);b=Math.min(a.selectedDay,this._getDaysInMonth(e,f))+(c=="D"?b:0);e=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(e,f,b)));a.selectedDay=e.getDate();a.drawMonth=a.selectedMonth=e.getMonth();a.drawYear=a.selectedYear=e.getFullYear();if(c=="M"||c=="Y")this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");b=c&&b<c?c:b;return b=a&&b>a?a:b},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear"); 15907if(b)b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){a=this._get(a,"numberOfMonths");return a==null?[1,1]:typeof a=="number"?[1,a]:a},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,e){var f=this._getNumberOfMonths(a); 15908c=this._daylightSavingAdjust(new Date(c,e+(b<0?b:f[0]*f[1]),1));b<0&&c.setDate(this._getDaysInMonth(c.getFullYear(),c.getMonth()));return this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!a||b.getTime()<=a.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a, 15909"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,e){if(!b){a.currentDay=a.selectedDay;a.currentMonth=a.selectedMonth;a.currentYear=a.selectedYear}b=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(e,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});d.fn.datepicker= 15910function(a){if(!this.length)return this;if(!d.datepicker.initialized){d(document).on('mousedown', d.datepicker._checkExternalClick).find("body").append(d.datepicker.dpDiv);d.datepicker.initialized=true}var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker, 15911[this[0]].concat(b));return this.each(function(){typeof a=="string"?d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this].concat(b)):d.datepicker._attachDatepicker(this,a)})};d.datepicker=new M;d.datepicker.initialized=false;d.datepicker.uuid=(new Date).getTime();d.datepicker.version="1.8.14";window["DP_jQuery_"+A]=d})(jQuery); 15912;/* 15913 * jQuery UI Progressbar 1.8.14 15914 * 15915 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 15916 * Dual licensed under the MIT or GPL Version 2 licenses. 15917 * http://jquery.org/license 15918 * 15919 * http://docs.jquery.com/UI/Progressbar 15920 * 15921 * Depends: 15922 * jquery.ui.core.js 15923 * jquery.ui.widget.js 15924 */ 15925(function(b,d){b.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()});this.valueDiv=b("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element);
15925this.oldValue=this._value();this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"); 15926this.valueDiv.remove();b.Widget.prototype.destroy.apply(this,arguments)},value:function(a){if(a===d)return this._value();this._setOption("value",a);return this},_setOption:function(a,c){if(a==="value"){this.options.value=c;this._refreshValue();this._value()===this.options.max&&this._trigger("complete")}b.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;if(typeof a!=="number")a=0;return Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100* 15927this._value()/this.options.max},_refreshValue:function(){var a=this.value(),c=this._percentage();if(this.oldValue!==a){this.oldValue=a;this._trigger("change")}this.valueDiv.toggle(a>this.min).toggleClass("ui-corner-right",a===this.options.max).width(c.toFixed(0)+"%");this.element.attr("aria-valuenow",a)}});b.extend(b.ui.progressbar,{version:"1.8.14"})})(jQuery); 15928; 15929 15930 15931 15932 15933 /* 15934 * jQuery UI selectmenu version 1.1.0 15935 * 15936 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) 15937 * Dual licensed under the MIT (MIT-LICENSE.txt) 15938 * and GPL (GPL-LICENSE.txt) licenses. 15939 * 15940 * http://docs.jquery.com/UI 15941 * https://github.com/fnagel/jquery-ui/wiki/Selectmenu 15942 */ 15943 15944(function($) { 15945 15946$.widget("ui.selectmenu", { 15947 getter: "value", 15948 version: "1.8", 15949 eventPrefix: "selectmenu", 15950 options: { 15951 transferClasses: true, 15952 typeAhead: "sequential", 15953 style: 'dropdown', 15954 positionOptions: { 15955 my: "left top", 15956 at: "left bottom", 15957 offset: null 15958 }, 15959 width: null, 15960 menuWidth: null, 15961 handleWidth: 26, 15962 maxHeight: null, 15963 icons: null, 15964 format: null, 15965 bgImage: function() {}, 15966 wrapperElement: "" 15967 }, 15968 15969 _create: function() { 15970 var self = this, o = this.options; 15971 15972 // set a default id value, generate a new random one if not set by developer 15973 var selectmenuId = this.element.attr('id') || 'ui-selectmenu-' + Math.random().toString(16).slice(2, 10); 15974 15975 // quick array of button and menu id's 15976 this.ids = [ selectmenuId + '-button', selectmenuId + '-menu' ]; 15977 15978 // define safe mouseup for future toggling 15979 this._safemouseup = true; 15980 15981 // create menu button wrapper 15982 this.newelement = $('<a class="' + this.widgetBaseClass + ' ui-widget ui-state-default ui-corner-all" id="' + this.ids[0] + '" role="button" href="#" tabindex="0" aria-haspopup="true" aria-owns="' + this.ids[1] + '"></a>') 15983 .insertAfter(this.element); 15984 this.newelement.wrap(o.wrapperElement); 15985 15986 // transfer tabindex 15987 var tabindex = this.element.attr('tabindex'); 15988 if (tabindex) { 15989 this.newelement.attr('tabindex', tabindex); 15990 } 15991 15992 // save reference to select in data for ease in calling methods 15993 this.newelement.data('selectelement', this.element); 15994 15995 // menu icon 15996 this.selectmenuIcon = $('<span class="' + this.widgetBaseClass + '-icon ui-icon"></span>') 15997 .prependTo(this.newelement); 15998 15999 // append status span to button 16000 this.newelement.prepend('<span class="' + self.widgetBaseClass + '-status" />'); 16001 16002 // make associated form label trigger focus 16003 $('label[for="' + this.element.attr('id') + '"]') 16004 .attr('for', this.ids[0]) 16005 .bind('click.selectmenu', function() { 16006 self.newelement[0].focus(); 16007 return false; 16008 }); 16009 16010 // click toggle for menu visibility 16011 this.newelement 16012 .bind('mousedown.selectmenu', function(event) { 16013 self._toggle(event, true); 16014 // make sure a click won't open/close instantly 16015 if (o.style == "popup") { 16016 self._safemouseup = false; 16017 setTimeout(function() { self._safemouseup = true; }, 300); 16018 } 16019 return false; 16020 }) 16021 .bind('click.selectmenu', function() { 16022 return false; 16023 }) 16024 .bind("keydown.selectmenu", function(event) { 16025 var ret = false; 16026 switch (event.keyCode) { 16027 case $.ui.keyCode.ENTER: 16028 ret = true; 16029 break; 16030 case $.ui.keyCode.SPACE: 16031 self._toggle(event); 16032 break; 16033 case $.ui.keyCode.UP: 16034 if (event.altKey) { 16035 self.open(event); 16036 } else { 16037 self._moveSelection(-1); 16038 } 16039 break; 16040 case $.ui.keyCode.DOWN: 16041 if (event.altKey) { 16042 self.open(event); 16043 } else { 16044 self._moveSelection(1); 16045 } 16046 break; 16047 case $.ui.keyCode.LEFT: 16048 self._moveSelection(-1); 16049 break; 16050 case $.ui.keyCode.RIGHT: 16051 self._moveSelection(1); 16052 break; 16053 case $.ui.keyCode.TAB: 16054 ret = true; 16055 break; 16056 default: 16057 ret = true; 16058 } 16059 return ret; 16060 }) 16061 .bind('keypress.selectmenu', function(event) { 16062 self._typeAhead(event.which, 'mouseup'); 16063 return true; 16064 }) 16065 .bind('mouseover.selectmenu focus.selectmenu', function() { 16066 if (!o.disabled) { 16067 $(this).addClass(self.widgetBaseClass + '-focus ui-state-hover'); 16068 } 16069 }) 16070 .bind('mouseout.selectmenu blur.selectmenu', function() { 16071 if (!o.disabled) { 16072 $(this).removeClass(self.widgetBaseClass + '-focus ui-state-hover'); 16073 } 16074 }); 16075 16076 // document click closes menu 16077 $(document).bind("mousedown.selectmenu", function(event) { 16078 self.close(event); 16079 }); 16080 16081 // change event on original selectmenu 16082 this.element 16083 .bind("click.selectmenu", function() { 16084 self._refreshValue(); 16085 }) 16086 // FIXME: newelement can be null under unclear circumstances in IE8 16087 // TODO not sure if this is still a problem (fnagel 20.03.11) 16088 .bind("focus.selectmenu", function() { 16089 if (self.newelement) { 16090 self.newelement[0].focus(); 16091 } 16092 }); 16093 16094 // set width when not set via options 16095 if (!o.width) { 16096 o.width = this.element.outerWidth(false); 16097 } 16098 // set menu button width 16099 this.newelement.width(o.width); 16100 16101 // hide original selectmenu element 16102 this.element.hide(); 16103 16104 // create menu portion, append to body 16105 this.list = $('<ul class="' + self.widgetBaseClass + '-menu ui-widget ui-widget-content" aria-hidden="true" role="listbox" aria-labelledby="' + this.ids[0] + '" id="' + this.ids[1] + '"></ul>').appendTo('body'); 16106 this.list.wrap(o.wrapperElement); 16107 16108 // transfer menu click to menu button 16109 this.list 16110 .bind("keydown.selectmenu", function(event) { 16111 var ret = false; 16112 switch (event.keyCode) { 16113 case $.ui.keyCode.UP: 16114 if (event.altKey) { 16115 self.close(event, true); 16116 } else { 16117 self._moveFocus(-1); 16118 } 16119 break; 16120 case $.ui.keyCode.DOWN: 16121 if (event.altKey) { 16122 self.close(event, true); 16123 } else { 16124 self._moveFocus(1); 16125 } 16126 break; 16127 case $.ui.keyCode.LEFT: 16128 self._moveFocus(-1); 16129 break; 16130 case $.ui.keyCode.RIGHT: 16131 self._moveFocus(1); 16132 break; 16133 case $.ui.keyCode.HOME: 16134 self._moveFocus(':first'); 16135 break; 16136 case $.ui.keyCode.PAGE_UP: 16137 self._scrollPage('up'); 16138 break; 16139 case $.ui.keyCode.PAGE_DOWN: 16140 self._scrollPage('down'); 16141 break; 16142 case $.ui.keyCode.END: 16143 self._moveFocus(':last'); 16144 break; 16145 case $.ui.keyCode.ENTER: 16146 case $.ui.keyCode.SPACE: 16147 self.close(event, true); 16148 $(event.target).parents('li:eq(0)').trigger('mouseup'); 16149 break; 16150 case $.ui.keyCode.TAB: 16151 ret = true; 16152 self.close(event, true); 16153 $(event.target).parents('li:eq(0)').trigger('mouseup'); 16154 break; 16155 case $.ui.keyCode.ESCAPE: 16156 self.close(event, true); 16157 break; 16158 default: 16159 ret = true; 16160 } 16161 return ret; 16162 }) 16163 .bind('keypress.selectmenu', function(event) {
16164 self._typeAhead(event.which, 'focus'); 16165 return true; 16166 }) 16167 // this allows for using the scrollbar in an overflowed list 16168 .bind( 'mousedown.selectmenu mouseup.selectmenu', function() { return false; }); 16169 16170 16171 // needed when window is resized 16172 $(window).bind( "resize.selectmenu", $.proxy( self._refreshPosition, this ) ); 16173 }, 16174 16175 _init: function() { 16176 var self = this, o = this.options; 16177 16178 // serialize selectmenu element options 16179 var selectOptionData = []; 16180 this.element 16181 .find('option') 16182 .each(function() { 16183 selectOptionData.push({ 16184 value: $(this).attr('value'), 16185 text: self._formatText($(this).text()), 16186 selected: $(this).attr('selected'), 16187 disabled: $(this).attr('disabled'), 16188 classes: $(this).attr('class'), 16189 typeahead: $(this).attr('typeahead'), 16190 parentOptGroup: $(this).parent('optgroup'), 16191 bgImage: o.bgImage.call($(this)) 16192 }); 16193 }); 16194 16195 // active state class is only used in popup style 16196 var activeClass = (self.options.style == "popup") ? " ui-state-active" : ""; 16197 16198 // empty list so we can refresh the selectmenu via selectmenu() 16199 this.list.html(""); 16200 16201 // write li's 16202 for (var i = 0; i < selectOptionData.length; i++) { 16203 var thisLi = $('<li role="presentation"' + (selectOptionData[i].disabled ? ' class="' + this.namespace + '-state-disabled' + '"' : '' ) + '><a href="#" tabindex="-1" role="option"' + (selectOptionData[i].disabled ? ' aria-disabled="true"' : '' ) + ' aria-selected="false"' + (selectOptionData[i].typeahead ? ' typeahead="' + selectOptionData[i].typeahead + '"' : '' ) + '>'+ selectOptionData[i].text +'</a></li>') 16204 .data('index', i) 16205 .addClass(selectOptionData[i].classes) 16206 .data('optionClasses', selectOptionData[i].classes || '') 16207 .bind("mouseup.selectmenu", function(event) { 16208 if (self._safemouseup && !self._disabled(event.currentTarget) && !self._disabled($( event.currentTarget ).parents( "ul>li." + self.widgetBaseClass + "-group " )) ) { 16209 var changed = $(this).data('index') != self._selectedIndex(); 16210 self.index($(this).data('index')); 16211 self.select(event); 16212 if (changed) { 16213 self.change(event); 16214 } 16215 self.close(event, true); 16216 } 16217 return false; 16218 }) 16219 .bind("click.selectmenu", function() { 16220 return false; 16221 }) 16222 .bind('mouseover.selectmenu focus.selectmenu', function(e) { 16223 // no hover if diabled 16224 if (!$(e.currentTarget).hasClass(self.namespace + '-state-disabled')) { 16225 self._selectedOptionLi().addClass(activeClass); 16226 self._focusedOptionLi().removeClass(self.widgetBaseClass + '-item-focus ui-state-hover'); 16227 $(this).removeClass('ui-state-active').addClass(self.widgetBaseClass + '-item-focus ui-state-hover'); 16228 } 16229 }) 16230 .bind('mouseout.selectmenu blur.selectmenu', function() { 16231 if ($(this).is(self._selectedOptionLi().selector)) { 16232 $(this).addClass(activeClass); 16233 } 16234 $(this).removeClass(self.widgetBaseClass + '-item-focus ui-state-hover'); 16235 }); 16236 16237 // optgroup or not... 16238 if ( selectOptionData[i].parentOptGroup.length ) { 16239 var optGroupName = self.widgetBaseClass + '-group-' + this.element.find( 'optgroup' ).index( selectOptionData[i].parentOptGroup ); 16240 if (this.list.find( 'li.' + optGroupName ).length ) { 16241 this.list.find( 'li.' + optGroupName + ':last ul' ).append( thisLi ); 16242 } else { 16243 $(' <li role="presentation" class="' + self.widgetBaseClass + '-group ' + optGroupName + (selectOptionData[i].parentOptGroup.attr("disabled") ? ' ' + this.namespace + '-state-disabled" aria-disabled="true"' : '"' ) + '><span class="' + self.widgetBaseClass + '-group-label">' + selectOptionData[i].parentOptGroup.attr('label') + '</span><ul></ul></li> ') 16244 .appendTo( this.list ) 16245 .find( 'ul' ) 16246 .append( thisLi ); 16247 } 16248 } else { 16249 thisLi.appendTo(this.list); 16250 } 16251 16252 // append icon if option is specified 16253 if (o.icons) { 16254 for (var j in o.icons) { 16255 if (thisLi.is(o.icons[j].find)) { 16256 thisLi 16257 .data('optionClasses', selectOptionData[i].classes + ' ' + self.widgetBaseClass + '-hasIcon') 16258 .addClass(self.widgetBaseClass + '-hasIcon'); 16259 var iconClass = o.icons[j].icon || ""; 16260 thisLi 16261 .find('a:eq(0)') 16262 .prepend('<span class="' + self.widgetBaseClass + '-item-icon ui-icon ' + iconClass + '"></span>'); 16263 if (selectOptionData[i].bgImage) { 16264 thisLi.find('span').css('background-image', selectOptionData[i].bgImage); 16265 } 16266 } 16267 } 16268 } 16269 } 16270 16271 // we need to set and unset the CSS classes for dropdown and popup style 16272 var isDropDown = (o.style == 'dropdown'); 16273 this.newelement 16274 .toggleClass(self.widgetBaseClass + "-dropdown", isDropDown) 16275 .toggleClass(self.widgetBaseClass + "-popup", !isDropDown); 16276 this.list
16277 .toggleClass(self.widgetBaseClass + "-menu-dropdown ui-corner-bottom", isDropDown) 16278 .toggleClass(self.widgetBaseClass + "-menu-popup ui-corner-all", !isDropDown) 16279 // add corners to top and bottom menu items 16280 .find('li:first') 16281 .toggleClass("ui-corner-top", !isDropDown) 16282 .end().find('li:last') 16283 .addClass("ui-corner-bottom"); 16284 this.selectmenuIcon 16285 .toggleClass('ui-icon-triangle-1-s', isDropDown) 16286 .toggleClass('ui-icon-triangle-2-n-s', !isDropDown); 16287 16288 // transfer classes to selectmenu and list 16289 if (o.transferClasses) { 16290 var transferClasses = this.element.attr('class') || ''; 16291 this.newelement.add(this.list).addClass(transferClasses); 16292 } 16293 16294 // set menu width to either menuWidth option value, width option value, or select width 16295 if (o.style == 'dropdown') { 16296 this.list.width(o.menuWidth ? o.menuWidth : o.width); 16297 } else { 16298 this.list.width(o.menuWidth ? o.menuWidth : o.width - o.handleWidth); 16299 } 16300 16301 // calculate default max height 16302 if (o.maxHeight) { 16303 // set max height from option 16304 if (o.maxHeight < this.list.height()) { 16305 this.list.height(o.maxHeight); 16306 } 16307 } else { 16308 if (!o.format && ($(window).height() / 3) < this.list.height()) { 16309 o.maxHeight = $(window).height() / 3; 16310 this.list.height(o.maxHeight); 16311 } 16312 } 16313 16314 // save reference to actionable li's (not group label li's) 16315 this._optionLis = this.list.find('li:not(.' + self.widgetBaseClass + '-group)'); 16316 16317 // transfer disabled state 16318 if ( this.element.attr( 'disabled' ) === true ) { 16319 this.disable(); 16320 } else { 16321 this.enable() 16322 } 16323 16324 // update value 16325 this.index(this._selectedIndex()); 16326 16327 // needed when selectmenu is placed at the very bottom / top of the page 16328 window.setTimeout(function() { 16329 self._refreshPosition(); 16330 }, 200); 16331 }, 16332 16333 destroy: function() { 16334 this.element.removeData( this.widgetName ) 16335 .removeClass( this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled' ) 16336 .removeAttr( 'aria-disabled' ) 16337 .unbind( ".selectmenu" ); 16338 16339 $( window ).unbind( ".selectmenu" ); 16340 $( document ).unbind( ".selectmenu" ); 16341 16342 // unbind click on label, reset its for attr 16343 $( 'label[for=' + this.newelement.attr('id') + ']' ) 16344 .attr( 'for', this.element.attr( 'id' ) ) 16345 .unbind( '.selectmenu' ); 16346 16347 if ( this.options.wrapperElement ) { 16348 this.newelement.find( this.options.wrapperElement ).remove(); 16349 this.list.find( this.options.wrapperElement ).remove(); 16350 } else { 16351 this.newelement.remove(); 16352 this.list.remove(); 16353 } 16354 this.element.show(); 16355 16356 // call widget destroy function 16357 $.Widget.prototype.destroy.apply(this, arguments); 16358 }, 16359 16360 _typeAhead: function(code, eventType){ 16361 var self = this, focusFound = false, C = String.fromCharCode(code).toUpperCase(); 16362 c = C.toLowerCase(); 16363 16364 if (self.options.typeAhead == 'sequential') { 16365 // clear the timeout so we can use _prevChar 16366 window.clearTimeout('ui.selectmenu-' + self.selectmenuId); 16367 16368 // define our find var 16369 var find = typeof(self._prevChar) == 'undefined' ? '' : self._prevChar.join(''); 16370 16371 function focusOptSeq(elem, ind, c){ 16372 focusFound = true; 16373 $(elem).trigger(eventType); 16374 typeof(self._prevChar) == 'undefined' ? self._prevChar = [c] : self._prevChar[self._prevChar.length] = c; 16375 } 16376 this.list.find('li a').each(function(i) { 16377 if (!focusFound) { 16378 // allow the typeahead attribute on the option tag for a more specific lookup 16379 var thisText = $(this).attr('typeahead') || $(this).text(); 16380 if (thisText.indexOf(find+C) == 0) { 16381 focusOptSeq(this,i,C) 16382 } else if (thisText.indexOf(find+c) == 0) { 16383 focusOptSeq(this,i,c) 16384 } 16385 } 16386 }); 16387 // set a 1 second timeout for sequenctial typeahead 16388 // keep this set even if we have no matches so it doesnt typeahead somewhere else 16389 window.setTimeout(function(el) { 16390 self._prevChar = undefined; 16391 }, 1000, self); 16392 16393 } else { 16394 //define self._prevChar if needed 16395 if (!self._prevChar){ self._prevChar = ['',0]; } 16396 16397 var focusFound = false; 16398 function focusOpt(elem, ind){ 16399 focusFound = true; 16400 $(elem).trigger(eventType); 16401 self._prevChar[1] = ind; 16402 } 16403 this.list.find('li a').each(function(i){ 16404 if(!focusFound){ 16405 var thisText = $(this).text(); 16406 if( thisText.indexOf(C) == 0 || thisText.indexOf(c) == 0){ 16407 if(self._prevChar[0] == C){ 16408 if(self._prevChar[1] < i){ focusOpt(this,i); } 16409 } 16410 else{ focusOpt(this,i); } 16411 } 16412 } 16413 }); 16414 this._prevChar[0] = C; 16415 } 16416 }, 16417 16418 // returns some usefull information, called by callbacks only 16419 _uiHash: function() { 16420 var index = this.index(); 16421 return { 16422 index: index, 16423 option: $("option", this.element).get(index), 16424 value: this.element[0].value 16425 }; 16426 }, 16427 16428 open: function(event) { 16429 var self = this; 16430 if ( this.newelement.attr("aria-disabled") != 'true' ) { 16431 this._closeOthers(event); 16432 this.newelement 16433 .addClass('ui-state-active'); 16434 if (self.options.wrapperElement) { 16435 this.list.parent().appendTo('body'); 16436 } else { 16437 this.list.appendTo('body'); 16438 } 16439
16440 this.list.addClass(self.widgetBaseClass + '-open') 16441 .attr('aria-hidden', false) 16442 .find('li:not(.' + self.widgetBaseClass + '-group):eq(' + this._selectedIndex() + ') a')[0].focus(); 16443 if ( this.options.style == "dropdown" ) { 16444 this.newelement.removeClass('ui-corner-all').addClass('ui-corner-top'); 16445 } 16446 this._refreshPosition(); 16447 this._trigger("open", event, this._uiHash()); 16448 } 16449 }, 16450 16451 close: function(event, retainFocus) { 16452 if ( this.newelement.is('.ui-state-active') ) { 16453 this.newelement 16454 .removeClass('ui-state-active'); 16455 this.list 16456 .attr('aria-hidden', true) 16457 .removeClass(this.widgetBaseClass + '-open'); 16458 if ( this.options.style == "dropdown" ) { 16459 this.newelement.removeClass('ui-corner-top').addClass('ui-corner-all'); 16460 } 16461 if ( retainFocus ) { 16462 this.newelement.focus(); 16463 } 16464 this._trigger("close", event, this._uiHash()); 16465 } 16466 }, 16467 16468 change: function(event) { 16469 this.element.trigger("change"); 16470 this._trigger("change", event, this._uiHash()); 16471 }, 16472 16473 select: function(event) { 16474 if (this._disabled(event.currentTarget)) { return false; } 16475 this._trigger("select", event, this._uiHash()); 16476 }, 16477 16478 _closeOthers: function(event) { 16479 $('.' + this.widgetBaseClass + '.ui-state-active').not(this.newelement).each(function() { 16480 $(this).data('selectelement').selectmenu('close', event); 16481 }); 16482 $('.' + this.widgetBaseClass + '.ui-state-hover').trigger('mouseout'); 16483 }, 16484 16485 _toggle: function(event, retainFocus) {
16486 if ( this.list.is('.' + this.widgetBaseClass + '-open') ) { 16487 this.close(event, retainFocus); 16488 } else { 16489 this.open(event); 16490 } 16491 }, 16492 16493 _formatText: function(text) { 16494 return (this.options.format ? this.options.format(text) : text); 16495 }, 16496 16497 _selectedIndex: function() { 16498 return this.element[0].selectedIndex; 16499 }, 16500 16501 _selectedOptionLi: function() { 16502 return this._optionLis.eq(this._selectedIndex()); 16503 }, 16504 16505 _focusedOptionLi: function() { 16506 return this.list.find('.' + this.widgetBaseClass + '-item-focus'); 16507 }, 16508 16509 _moveSelection: function(amt, recIndex) { 16510 var currIndex = parseInt(this._selectedOptionLi().data('index') || 0, 10); 16511 var newIndex = currIndex + amt; 16512 // do not loop when using up key 16513 16514 if (newIndex < 0) { 16515 newIndex = 0; 16516 } 16517 if (newIndex > this._optionLis.size() - 1) { 16518 newIndex = this._optionLis.size() - 1; 16519 } 16520 //Occurs when a full loop has been made 16521 if (newIndex === recIndex) { return false; } 16522 16523 if (this._optionLis.eq(newIndex).hasClass( this.namespace + '-state-disabled' )) { 16524 // if option at newIndex is disabled, call _moveFocus, incrementing amt by one 16525 (amt > 0) ? ++amt : --amt; 16526 this._moveSelection(amt, newIndex); 16527 } else { 16528 return this._optionLis.eq(newIndex).trigger('mouseup'); 16529 } 16530 }, 16531 16532 _moveFocus: function(amt, recIndex) { 16533 if (!isNaN(amt)) { 16534 var currIndex = parseInt(this._focusedOptionLi().data('index') || 0, 10); 16535 var newIndex = currIndex + amt; 16536 } 16537 else { 16538 var newIndex = parseInt(this._optionLis.filter(amt).data('index'), 10); 16539 } 16540 16541 if (newIndex < 0) { 16542 newIndex = 0; 16543 } 16544 if (newIndex > this._optionLis.size() - 1) { 16545 newIndex = this._optionLis.size() - 1; 16546 } 16547 16548 //Occurs when a full loop has been made 16549 if (newIndex === recIndex) { return false; } 16550 16551 var activeID = this.widgetBaseClass + '-item-' + Math.round(Math.random() * 1000); 16552 16553 this._focusedOptionLi().find('a:eq(0)').attr('id', ''); 16554 16555 if (this._optionLis.eq(newIndex).hasClass( this.namespace + '-state-disabled' )) { 16556 // if option at newIndex is disabled, call _moveFocus, incrementing amt by one 16557 (amt > 0) ? ++amt : --amt; 16558 this._moveFocus(amt, newIndex); 16559 } else { 16560 this._optionLis.eq(newIndex).find('a:eq(0)').attr('id',activeID).focus(); 16561 } 16562 16563 this.list.attr('aria-activedescendant', activeID); 16564 }, 16565 16566 _scrollPage: function(direction) { 16567 var numPerPage = Math.floor(this.list.outerHeight(false) / this.list.find('li:first').outerHeight(false)); 16568 numPerPage = (direction == 'up' ? -numPerPage : numPerPage); 16569 this._moveFocus(numPerPage); 16570 }, 16571 16572 _setOption: function(key, value) { 16573 this.options[key] = value; 16574 // set 16575 if (key == 'disabled') { 16576 this.close(); 16577 this.element 16578 .add(this.newelement) 16579 .add(this.list)[value ? 'addClass' : 'removeClass']( 16580 this.widgetBaseClass + '-disabled' + ' ' + 16581 this.namespace + '-state-disabled') 16582 .attr("aria-disabled", value); 16583 } 16584 }, 16585 16586 disable: function(index, type){ 16587 // if options is not provided, call the parents disable function 16588 if ( typeof( index ) == 'undefined' ) { 16589 this._setOption( 'disabled', true ); 16590 } else { 16591 if ( type == "optgroup" ) { 16592 this._disableOptgroup(index); 16593 } else { 16594 this._disableOption(index); 16595 } 16596 } 16597 }, 16598 16599 enable: function(index, type) { 16600 // if options is not provided, call the parents enable function 16601 if ( typeof( index ) == 'undefined' ) { 16602 this._setOption('disabled', false); 16603 } else { 16604 if ( type == "optgroup" ) { 16605 this._enableOptgroup(index); 16606 } else { 16607 this._enableOption(index); 16608 } 16609 } 16610 }, 16611 16612 _disabled: function(elem) { 16613 return $(elem).hasClass( this.namespace + '-state-disabled' ); 16614 }, 16615 16616 16617 _disableOption: function(index) { 16618 var optionElem = this._optionLis.eq(index); 16619 if (optionElem) { 16620 optionElem.addClass(this.namespace + '-state-disabled') 16621 .find("a").attr("aria-disabled", true); 16622 this.element.find("option").eq(index).attr("disabled", "disabled"); 16623 } 16624 }, 16625 16626 _enableOption: function(index) { 16627 var optionElem = this._optionLis.eq(index); 16628 if (optionElem) { 16629 optionElem.removeClass( this.namespace + '-state-disabled' ) 16630 .find("a").attr("aria-disabled", false); 16631 this.element.find("option").eq(index).removeAttr("disabled"); 16632 } 16633 }, 16634 16635 _disableOptgroup: function(index) { 16636 var optGroupElem = this.list.find( 'li.' + this.widgetBaseClass + '-group-' + index ); 16637 if (optGroupElem) { 16638 optGroupElem.addClass(this.namespace + '-state-disabled') 16639 .attr("aria-disabled", true); 16640 this.element.find("optgroup").eq(index).attr("disabled", "disabled"); 16641 } 16642 }, 16643 16644 _enableOptgroup: function(index) { 16645 var optGroupElem = this.list.find( 'li.' + this.widgetBaseClass + '-group-' + index ); 16646 if (optGroupElem) { 16647 optGroupElem.removeClass(this.namespace + '-state-disabled') 16648 .attr("aria-disabled", false); 16649 this.element.find("optgroup").eq(index).removeAttr("disabled"); 16650 } 16651 }, 16652 16653 index: function(newValue) { 16654 if (arguments.length) { 16655 if (!this._disabled($(this._optionLis[newValue]))) { 16656 this.element[0].selectedIndex = newValue; 16657 this._refreshValue(); 16658 } else { 16659 return false; 16660 } 16661 } else { 16662 return this._selectedIndex(); 16663 } 16664 }, 16665 16666 value: function(newValue) { 16667 if (arguments.length) { 16668 this.element[0].value = newValue; 16669 this._refreshValue(); 16670 } else { 16671 return this.element[0].value; 16672 } 16673 }, 16674 16675 _refreshValue: function() { 16676 var activeClass = (this.options.style == "popup") ? " ui-state-active" : ""; 16677 var activeID = this.widgetBaseClass + '-item-' + Math.round(Math.random() * 1000); 16678 // deselect previous 16679 this.list 16680 .find('.' + this.widgetBaseClass + '-item-selected') 16681 .removeClass(this.widgetBaseClass + "-item-selected" + activeClass) 16682 .find('a') 16683 .attr('aria-selected', 'false') 16684 .attr('id', ''); 16685 // select new 16686 this._selectedOptionLi() 16687 .addClass(this.widgetBaseClass + "-item-selected" + activeClass) 16688 .find('a') 16689 .attr('aria-selected', 'true') 16690 .attr('id', activeID); 16691 16692 // toggle any class brought in from option 16693 var currentOptionClasses = (this.newelement.data('optionClasses') ? this.newelement.data('optionClasses') : ""); 16694 var newOptionClasses = (this._selectedOptionLi().data('optionClasses') ? this._selectedOptionLi().data('optionClasses') : ""); 16695 this.newelement 16696 .removeClass(currentOptionClasses) 16697 .data('optionClasses', newOptionClasses) 16698 .addClass( newOptionClasses ) 16699 .find('.' + this.widgetBaseClass + '-status') 16700 .html( 16701 this._selectedOptionLi() 16702 .find('a:eq(0)') 16703 .html() 16704 ); 16705 16706 this.list.attr('aria-activedescendant', activeID); 16707 }, 16708 16709 _refreshPosition: function() { 16710 var o = this.options; 16711 // if its a native pop-up we need to calculate the position of the selected li 16712 if (o.style == "popup" && !o.positionOptions.offset) { 16713 var selected = this._selectedOptionLi(); 16714 var _offset = "0 -" + (selected.outerHeight(false) + selected.offset().top - this.list.offset().top); 16715 } 16716 // update zIndex if jQuery UI is able to process 16717 var zIndexElement = this.element.zIndex(); 16718 if (zIndexElement) { 16719 this.list.css({ 16720 zIndex: zIndexElement 16721 }); 16722 } 16723 this.list.position({ 16724 // set options for position plugin 16725 of: o.positionOptions.of || this.newelement, 16726 my: o.positionOptions.my, 16727 at: o.positionOptions.at, 16728 offset: o.positionOptions.offset || _offset, 16729 collision: o.positionOptions.collision || 'flip' 16730 }); 16731 } 16732}); 16733 16734})(jQuery); 16735 16736 16737var formatOptionByPipe = function(text){ 16738 if(!text.replace){ 16739 return(""); 16740 } 16741 16742 var newText = text; 16743 //array of find replaces 16744 var findreps = [ 16745 {find:/^([^\-]+) \- /g, rep: '<span class="ui-selectmenu-item-header">$1</span>'}, 16746 {find:/([^\|><]+) \| /g, rep: '<span class="ui-selectmenu-item-content">$1</span>'}, 16747 {find:/([^\|><\(\)]+) (\()/g, rep: '<span class="ui-selectmenu-item-content">$1</span>$2'}, 16748 {find:/([^\|><\(\)]+)$/g, rep: '<span class="ui-selectmenu-item-content">$1</span>'},
16749 {find:/(\([^\|><]+\))$/g, rep: '<span class="ui-selectmenu-item-footer">$1</span>'} 16750 ]; 16751 16752 for(var i in findreps){ 16753 newText = newText.replace(findreps[i].find, findreps[i].rep); 16754 } 16755 return newText; 16756}; 16757 16758 16759 16760; 16761////pf: javascript/jquery-timepicker.js 16762/* 16763* jQuery timepicker addon 16764* By: Trent Richardson [http://trentrichardson.com] 16765* Version 0.9.8 16766* Last Modified: 12/03/2011 16767* 16768* Copyright 2011 Trent Richardson 16769* Dual licensed under the MIT and GPL licenses. 16770* http://trentrichardson.com/Impromptu/GPL-LICENSE.txt 16771* http://trentrichardson.com/Impromptu/MIT-LICENSE.txt 16772* 16773* HERES THE CSS: 16774* .ui-timepicker-div .ui-widget-header { margin-bottom: 8px; } 16775* .ui-timepicker-div dl { text-align: left; } 16776* .ui-timepicker-div dl dt { height: 25px; margin-bottom: -25px; } 16777* .ui-timepicker-div dl dd { margin: 0 10px 10px 65px; } 16778* .ui-timepicker-div td { font-size: 90%; } 16779* .ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; } 16780*/ 16781 16782(function ($) { 16783 16784 $.extend($.ui, { timepicker: { version: "0.9.8"} }); 16785 16786 /* Time picker manager. 16787 Use the singleton instance of this class, $.timepicker, to interact with the time picker. 16788 Settings for (groups of) time pickers are maintained in an instance object, 16789 allowing multiple different settings on the same page. */ 16790 16791 function Timepicker() { 16792 this.regional = []; // Available regional settings, indexed by language code 16793 this.regional[''] = { // Default regional settings 16794 currentText: 'Now', 16795 closeText: 'Done', 16796 ampm: true, 16797 amNames: ['AM', 'A', 'am', 'a'], 16798 pmNames: ['PM', 'P', 'pm', 'p'], 16799 timeFormat: 'h:mm tt', 16800 timeSuffix: '', 16801 timeOnlyTitle: 'Choose Time', 16802 timeText: 'Time', 16803 hourText: 'Hour', 16804 minuteText: 'Minute', 16805 secondText: 'Second', 16806 millisecText: 'Millisecond', 16807 timezoneText: 'Time Zone' 16808 }; 16809 this._defaults = { // Global defaults for all the datetime picker instances 16810 showButtonPanel: true, 16811 timeOnly: false, 16812 showHour: false, 16813 showMinute: false, 16814 showSecond: false, 16815 showMillisec: false, 16816 showTimezone: false, 16817 showTime: false, 16818 hour: 9, 16819 minute: 0, 16820 second: 0, 16821 millisec: 0, 16822 timezone: '+0000', 16823 hourMin: 0, 16824 minuteMin: 0, 16825 secondMin: 0, 16826 millisecMin: 0, 16827 hourMax: 23, 16828 minuteMax: 59, 16829 secondMax: 59, 16830 millisecMax: 999, 16831 minDateTime: null, 16832 maxDateTime: null, 16833 onSelect: null, 16834 alwaysSetTime: true, 16835 separator: ' ', 16836 altFieldTimeOnly: true, 16837 showTimepicker: true, 16838 timezoneIso8609: false, 16839 timezoneList: null 16840 }; 16841 $.extend(this._defaults, this.regional['']); 16842 } 16843 16844 $.extend(Timepicker.prototype, { 16845 $input: null, 16846 $altInput: null, 16847 $timeObj: null, 16848 inst: null, 16849 timezone_select: null, 16850 hour: 0, 16851 minute: 0, 16852 second: 0, 16853 millisec: 0, 16854 timezone: '+0000', 16855 hourMinOriginal: null, 16856 minuteMinOriginal: null, 16857 secondMinOriginal: null, 16858 millisecMinOriginal: null, 16859 hourMaxOriginal: null, 16860 minuteMaxOriginal: null, 16861 secondMaxOriginal: null, 16862 millisecMaxOriginal: null, 16863 ampm: '', 16864 formattedDate: '', 16865 formattedTime: '', 16866 formattedDateTime: '', 16867 timezoneList: null, 16868 16869 /* Override the default settings for all instances of the time picker. 16870 @param settings object - the new settings to use as defaults (anonymous object) 16871 @return the manager object */ 16872 setDefaults: function (settings) { 16873 extendRemove(this._defaults, settings || {}); 16874 return this; 16875 }, 16876 16877 //######################################################################## 16878 // Create a new Timepicker instance 16879 //######################################################################## 16880 _newInst: function ($input, o) { 16881 var tp_inst = new Timepicker(), 16882 inlineSettings = {}; 16883 16884 for (var attrName in this._defaults) { 16885 var attrValue = $input.attr('time:' + attrName); 16886 if (attrValue) { 16887 try { 16888 inlineSettings[attrName] = eval(attrValue); 16889 } catch (err) { 16890 inlineSettings[attrName] = attrValue; 16891 } 16892 } 16893 } 16894 tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, o, { 16895 beforeShow: function (input, dp_inst) { 16896 if ($.isFunction(o.beforeShow)) 16897 o.beforeShow(input, dp_inst, tp_inst); 16898 }, 16899 onChangeMonthYear: function (year, month, dp_inst) { 16900 // Update the time as well : this prevents the time from disappearing from the $input field. 16901 tp_inst._updateDateTime(dp_inst); 16902 if ($.isFunction(o.onChangeMonthYear)) 16903 o.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst); 16904 }, 16905 onClose: function (dateText, dp_inst) { 16906 if (tp_inst.timeDefined === true && $input.val() != '') 16907 tp_inst._updateDateTime(dp_inst); 16908 if ($.isFunction(o.onClose)) 16909 o.onClose.call($input[0], dateText, dp_inst, tp_inst); 16910 }, 16911 timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker'); 16912 }); 16913 tp_inst.amNames = $.map(tp_inst._defaults.amNames, function (val) { return val.toUpperCase() }); 16914 tp_inst.pmNames = $.map(tp_inst._defaults.pmNames, function (val) { return val.toUpperCase() }); 16915 16916 if (tp_inst._defaults.timezoneList === null) { 16917 var timezoneList = [];
16918 for (var i = -11; i <= 12; i++) 16919 timezoneList.push((i >= 0 ? '+' : '-') + ('0' + Math.abs(i).toString()).slice(-2) + '00'); 16920 if (tp_inst._defaults.timezoneIso8609) 16921 timezoneList = $.map(timezoneList, function (val) { 16922 return val == '+0000' ? 'Z' : (val.substring(0, 3) + ':' + val.substring(3)); 16923 }); 16924 tp_inst._defaults.timezoneList = timezoneList; 16925 } 16926 16927 tp_inst.hour = tp_inst._defaults.hour; 16928 tp_inst.minute = tp_inst._defaults.minute; 16929 tp_inst.second = tp_inst._defaults.second; 16930 tp_inst.millisec = tp_inst._defaults.millisec; 16931 tp_inst.ampm = ''; 16932 tp_inst.$input = $input; 16933 16934 if (o.altField) 16935 tp_inst.$altInput = $(o.altField) 16936 .css({ cursor: 'pointer' }) 16937 .focus(function () { $input.trigger("focus"); }); 16938 16939 if (tp_inst._defaults.minDate == 0 || tp_inst._defaults.minDateTime == 0) { 16940 tp_inst._defaults.minDate = new Date(); 16941 } 16942 if (tp_inst._defaults.maxDate == 0 || tp_inst._defaults.maxDateTime == 0) { 16943 tp_inst._defaults.maxDate = new Date(); 16944 } 16945 16946 // datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime.. 16947 if (tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date) 16948 tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime()); 16949 if (tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date) 16950 tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime()); 16951 if (tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date) 16952 tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime()); 16953 if (tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date) 16954 tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime()); 16955 return tp_inst; 16956 }, 16957 16958 //######################################################################## 16959 // add our sliders to the calendar 16960 //######################################################################## 16961 _addTimePicker: function (dp_inst) { 16962 var currDT = (this.$altInput && this._defaults.altFieldTimeOnly) ? 16963 this.$input.val() + ' ' + this.$altInput.val() : 16964 this.$input.val(); 16965 16966 this.timeDefined = this._parseTime(currDT); 16967 this._limitMinMaxDateTime(dp_inst, false); 16968 this._injectTimePicker(); 16969 }, 16970 16971 //######################################################################## 16972 // parse the time string from input value or _setTime 16973 //######################################################################## 16974 _parseTime: function (timeString, withDate) { 16975 var regstr = this._defaults.timeFormat.toString() 16976 .replace(/h{1,2}/ig, '(\\d?\\d)') 16977 .replace(/:{1}/ig, '([:]?)') 16978 .replace(/m{2}/ig, '(\\d{0}|\\d{2})') 16979 .replace(/s{2}/ig, '(\\d\\d)') 16980 .replace(/l{1}/ig, '(\\d?\\d?\\d)') 16981 .replace(/t{1,2}/ig, this._getPatternAmpm()) 16982 .replace(/z{1}/ig, '(z|[-+]\\d\\d:?\\d\\d)?') 16983 .replace(/\s/g, '\\s?') + this._defaults.timeSuffix + '$', 16984 order = this._getFormatPositions(), 16985 ampm = '', 16986 treg; 16987 16988 if (!this.inst) this.inst = $.datepicker._getInst(this.$input[0]); 16989 16990 if (withDate || !this._defaults.timeOnly) { 16991 // the time should come after x number of characters and a space. 16992 // x = at least the length of text specified by the date format 16993 var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat'); 16994 // escape special regex characters in the seperator 16995 var specials = new RegExp("[.*+?|()\\[\\]{}\\\\]", "g"); 16996 regstr = '.{' + dp_dateFormat.length + ',}' + this._defaults.separator.replace(specials, "\\$&") + regstr; 16997 } 16998
16999 treg = timeString.match(new RegExp(regstr, 'i')); 17000 if (treg) { 17001 17002 if (order.t !== -1) { 17003 if (treg[order.t] === undefined || treg[order.t].length === 0) { 17004 ampm = ''; 17005 this.ampm = ''; 17006 } else { 17007 ampm = $.inArray(treg[order.t].toUpperCase(), this.amNames) !== -1 ? 'AM' : 'PM'; 17008 this.ampm = this._defaults[ampm == 'AM' ? 'amNames' : 'pmNames'][0]; 17009 } 17010 } 17011 17012 if (order.h !== -1) { 17013 if (ampm == 'AM' && treg[order.h] == '12') 17014 this.hour = 0; // 12am = 0 hour 17015 else if (ampm == 'PM' && treg[order.h] != '12') 17016 this.hour = (parseFloat(treg[order.h]) + 12).toFixed(0); // 12pm = 12 hour, any other pm = hour + 12 17017 else this.hour = Number(treg[order.h]); 17018 } 17019 17020 if (order.m !== -1) this.minute = Number(treg[order.m]); 17021 if (order.s !== -1) this.second = Number(treg[order.s]); 17022 if (order.l !== -1) this.millisec = Number(treg[order.l]); 17023 if (order.z !== -1 && treg[order.z] !== undefined) { 17024 var tz = treg[order.z].toUpperCase(); 17025 switch (tz.length) { 17026 case 1: // Z 17027 tz = this._defaults.timezoneIso8609 ? 'Z' : '+0000'; 17028 break; 17029 case 5: // +hhmm 17030 if (this._defaults.timezoneIso8609) 17031 tz = tz.substring(1) == '0000' 17032 ? 'Z' 17033 : tz.substring(0, 3) + ':' + tz.substring(3); 17034 break; 17035 case 6: // +hh:mm 17036 if (!this._defaults.timezoneIso8609) 17037 tz = tz == 'Z' || tz.substring(1) == '00:00' 17038 ? '+0000' 17039 : tz.replace(/:/, ''); 17040 else if (tz.substring(1) == '00:00') 17041 tz = 'Z'; 17042 break; 17043 } 17044 this.timezone = tz; 17045 } 17046 17047 return true; 17048 17049 } 17050 return false; 17051 }, 17052 17053 //######################################################################## 17054 // pattern for standard and localized AM/PM markers 17055 //######################################################################## 17056 _getPatternAmpm: function () { 17057 var markers = []; 17058 o = this._defaults; 17059 if (o.amNames) 17060 $.merge(markers, o.amNames); 17061 if (o.pmNames) 17062 $.merge(markers, o.pmNames); 17063 markers = $.map(markers, function (val) { return val.replace(/[.*+?|()\[\]{}\\]/g, '\\$&') }); 17064 return '(' + markers.join('|') + ')?'; 17065 }, 17066 17067 //######################################################################## 17068 // figure out position of time elements.. cause js cant do named captures 17069 //######################################################################## 17070 _getFormatPositions: function () { 17071 var finds = this._defaults.timeFormat.toLowerCase().match(/(h{1,2}|[:]{1}|m{2}|s{2}|l{1}|t{1,2}|z)/g), 17072 orders = { h: -1, c: -1, m: -1, s: -1, l: -1, t: -1, z: -1 }; 17073 17074 if (finds) 17075 for (var i = 0; i < finds.length; i++) 17076 if (orders[finds[i].toString().charAt(0)] == -1) 17077 orders[finds[i].toString().charAt(0)] = i + 1; 17078 17079 return orders; 17080 }, 17081 17082 //######################################################################## 17083 // generate and inject html for timepicker into ui datepicker 17084 //######################################################################## 17085 _injectTimePicker: function () { 17086 var $dp = this.inst.dpDiv, 17087 o = this._defaults, 17088 tp_inst = this, 17089 dp_id = this.inst.id.toString().replace(/([^A-Za-z0-9_])/g, ''); 17090 17091 // Prevent displaying twice 17092 if ($dp.find("div#ui-timepicker-div-" + dp_id).length === 0 && o.showTimepicker) { 17093 var html = '<div class="ui-timepicker-div" id="ui-timepicker-div-' + dp_id + '"></div>'; 17094 $tp = $(html); 17095 17096 // if we only want time picker... 17097 if (o.timeOnly === true) { 17098 $tp.prepend( 17099 '<div class="ui-widget-header ui-helper-clearfix ui-corner-all">' + 17100 '<div class="ui-datepicker-title">' + o.timeOnlyTitle + '</div>' + 17101 '</div>'); 17102 $dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide(); 17103 } 17104 17105 /* TODO: would be good to have the timezone as part of the datepicker control 17106 this.timezone_select = $tp.find('#ui_tpicker_timezone_' + dp_id).append('<select></select>').find("select"); 17107 $.fn.append.apply(this.timezone_select, 17108 $.map(o.timezoneList, function (val, idx) { 17109 return $("<option />") 17110 .val(typeof val == "object" ? val.value : val) 17111 .text(typeof val == "object" ? val.label : val); 17112 }) 17113 ); 17114 this.timezone_select.val((typeof this.timezone != "undefined" && this.timezone != null && this.timezone != "") ? this.timezone : o.timezone); 17115 this.timezone_select.change(function () { 17116 tp_inst._onTimeChange(); 17117 }); 17118 */ 17119 17120 var $buttonPanel = $dp.find('.ui-datepicker-buttonpane'); 17121 if ($buttonPanel.length) $buttonPanel.before($tp); 17122 else $dp.append($tp); 17123 17124 this.$timeObj = $tp.find('#ui_tpicker_time_' + dp_id); 17125 17126 if (this.inst !== null) { 17127 var timeDefined = this.timeDefined; 17128 this._onTimeChange(); 17129 this.timeDefined = timeDefined; 17130 } 17131 17132 } 17133 }, 17134 17135 //######################################################################## 17136 // This function tries to limit the ability to go outside the 17137 // min/max date range 17138 //######################################################################## 17139 _limitMinMaxDateTime: function (dp_inst) { 17140 var o = this._defaults, 17141 dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay); 17142 17143 if (!this._defaults.showTimepicker) return; // No time so nothing to check here 17144 17145 if ($.datepicker._get(dp_inst, 'minDateTime') !== null && $.datepicker._get(dp_inst, 'minDateTime') !== undefined && dp_date) { 17146 var minDateTime = $.datepicker._get(dp_inst, 'minDateTime'), 17147 minDateTimeDate = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), 0, 0, 0, 0); 17148
17149 if (this.hourMinOriginal === null || this.minuteMinOriginal === null || this.secondMinOriginal === null || this.millisecMinOriginal === null) { 17150 this.hourMinOriginal = o.hourMin; 17151 this.minuteMinOriginal = o.minuteMin; 17152 this.secondMinOriginal = o.secondMin; 17153 this.millisecMinOriginal = o.millisecMin; 17154 } 17155 17156 if (dp_inst.settings.timeOnly || minDateTimeDate.getTime() == dp_date.getTime()) { 17157 this._defaults.hourMin = minDateTime.getHours(); 17158 if (this.hour <= this._defaults.hourMin) { 17159 this.hour = this._defaults.hourMin; 17160 this._defaults.minuteMin = minDateTime.getMinutes(); 17161 if (this.minute <= this._defaults.minuteMin) { 17162 this.minute = this._defaults.minuteMin; 17163 this._defaults.secondMin = minDateTime.getSeconds(); 17164 } else if (this.second <= this._defaults.secondMin) { 17165 this.second = this._defaults.secondMin; 17166 this._defaults.millisecMin = minDateTime.getMilliseconds(); 17167 } else { 17168 if (this.millisec < this._defaults.millisecMin) 17169 this.millisec = this._defaults.millisecMin; 17170 this._defaults.millisecMin = this.millisecMinOriginal; 17171 } 17172 } else { 17173 this._defaults.minuteMin = this.minuteMinOriginal; 17174 this._defaults.secondMin = this.secondMinOriginal; 17175 this._defaults.millisecMin = this.millisecMinOriginal; 17176 } 17177 } else { 17178 this._defaults.hourMin = this.hourMinOriginal; 17179 this._defaults.minuteMin = this.minuteMinOriginal; 17180 this._defaults.secondMin = this.secondMinOriginal; 17181 this._defaults.millisecMin = this.millisecMinOriginal; 17182 } 17183 } 17184 17185 if ($.datepicker._get(dp_inst, 'maxDateTime') !== null && $.datepicker._get(dp_inst, 'maxDateTime') !== undefined && dp_date) { 17186 var maxDateTime = $.datepicker._get(dp_inst, 'maxDateTime'), 17187 maxDateTimeDate = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), 0, 0, 0, 0); 17188 17189 if (this.hourMaxOriginal === null || this.minuteMaxOriginal === null || this.secondMaxOriginal === null) { 17190 this.hourMaxOriginal = o.hourMax; 17191 this.minuteMaxOriginal = o.minuteMax; 17192 this.secondMaxOriginal = o.secondMax; 17193 this.millisecMaxOriginal = o.millisecMax; 17194 } 17195 17196 if (dp_inst.settings.timeOnly || maxDateTimeDate.getTime() == dp_date.getTime()) { 17197 this._defaults.hourMax = maxDateTime.getHours(); 17198 if (this.hour >= this._defaults.hourMax) { 17199 this.hour = this._defaults.hourMax; 17200 this._defaults.minuteMax = maxDateTime.getMinutes(); 17201 if (this.minute >= this._defaults.minuteMax) { 17202 this.minute = this._defaults.minuteMax; 17203 this._defaults.secondMax = maxDateTime.getSeconds(); 17204 } else if (this.second >= this._defaults.secondMax) { 17205 this.second = this._defaults.secondMax; 17206 this._defaults.millisecMax = maxDateTime.getMilliseconds(); 17207 } else { 17208 if (this.millisec > this._defaults.millisecMax) this.millisec = this._defaults.millisecMax; 17209 this._defaults.millisecMax = this.millisecMaxOriginal; 17210 } 17211 } else { 17212 this._defaults.minuteMax = this.minuteMaxOriginal; 17213 this._defaults.secondMax = this.secondMaxOriginal; 17214 this._defaults.millisecMax = this.millisecMaxOriginal; 17215 } 17216 } else { 17217 this._defaults.hourMax = this.hourMaxOriginal; 17218 this._defaults.minuteMax = this.minuteMaxOriginal; 17219 this._defaults.secondMax = this.secondMaxOriginal; 17220 this._defaults.millisecMax = this.millisecMaxOriginal; 17221 } 17222 } 17223 }, 17224 17225 17226 //######################################################################## 17227 // when a slider moves, set the internal time... 17228 // on time change is also called when the time is updated in the text field 17229 //######################################################################## 17230 _onTimeChange: function () { 17231 let timezone = (this.timezone_select) ? this.timezone_select.val() : false; 17232 let o = this._defaults; 17233 17234 const hasChanged = timezone != this.timezone; 17235 17236 if (hasChanged) { 17237 if (!this.inst) { 17238 this.inst = $.datepicker._getInst(this.$input[0]); 17239 } 17240 this._limitMinMaxDateTime(this.inst, true); 17241 } 17242 17243 this._formatTime(); 17244 if (this.$timeObj) this.$timeObj.text(this.formattedTime + o.timeSuffix); 17245 this.timeDefined = true; 17246 if (hasChanged) this._updateDateTime(); 17247 }, 17248 17249 //######################################################################## 17250 // call custom onSelect. 17251 // bind to sliders slidestop, and grid click. 17252 //######################################################################## 17253 _onSelectHandler: function () { 17254 var onSelect = this._defaults.onSelect; 17255 var inputEl = this.$input ? this.$input[0] : null; 17256 if (onSelect && inputEl) { 17257 onSelect.apply(inputEl, [this.formattedDateTime, this]); 17258 } 17259 }, 17260 17261 //######################################################################## 17262 // format the time all pretty... 17263 //######################################################################## 17264 _formatTime: function (time, format, ampm) { 17265 if (ampm == undefined) ampm = this._defaults.ampm; 17266 time = time || { 17267 hour: this.hour, 17268 minute: this.minute, 17269 second: this.second, 17270 millisec: this.millisec, 17271 ampm: this.hour >= 12 ? 'PM' : 'AM', 17272 timezone: this.timezone 17273 }; 17274 var tmptime = (format || this._defaults.timeFormat).toString(); 17275 17276 var hour = parseInt(time.hour, 10); 17277 if (ampm) { 17278 if (!$.inArray(time.ampm.toUpperCase(), this.amNames) !== -1) 17279 hour = hour % 12; 17280 if (hour === 0) 17281 hour = 12; 17282 } 17283 tmptime = tmptime.replace(/(?:hh?|mm?|ss?|[tT]{1,2}|[lz])/g, function (match) { 17284 switch (match.toLowerCase()) { 17285 case 'hh': return ('0' + hour).slice(-2); 17286 case 'h': return hour; 17287 case 'mm': return ('0' + time.minute).slice(-2); 17288 case 'm': return time.minute; 17289 case 'ss': return ('0' + time.second).slice(-2); 17290 case 's': return time.second; 17291 case 'l': return ('00' + time.millisec).slice(-3); 17292 case 'z': return time.timezone; 17293 case 't': case 'tt': 17294 if (ampm) { 17295 var _ampm = time.ampm; 17296 if (match.length == 1) 17297 _ampm = _ampm.charAt(0);
17298 return match.charAt(0) == 'T' ? _ampm.toUpperCase() : _ampm.toLowerCase(); 17299 } 17300 return ''; 17301 } 17302 }); 17303 17304 if (arguments.length) return tmptime; 17305 else this.formattedTime = tmptime; 17306 }, 17307 17308 //######################################################################## 17309 // update our input with the new date time.. 17310 //######################################################################## 17311 _updateDateTime: function (dp_inst) { 17312 dp_inst = this.inst || dp_inst; 17313 var dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)), 17314 dateFmt = $.datepicker._get(dp_inst, 'dateFormat'), 17315 formatCfg = $.datepicker._getFormatConfig(dp_inst), 17316 timeAvailable = dt !== null && this.timeDefined; 17317 this.formattedDate = $.datepicker.formatDate(dateFmt, (dt === null ? new Date() : dt), formatCfg); 17318 var formattedDateTime = this.formattedDate; 17319 if (dp_inst.lastVal !== undefined && (dp_inst.lastVal.length > 0 && this.$input.val().length === 0)) 17320 return; 17321 17322 if (this._defaults.timeOnly === true) { 17323 formattedDateTime = this.formattedTime; 17324 } else if (this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) { 17325 formattedDateTime += this._defaults.separator + this.formattedTime + this._defaults.timeSuffix; 17326 } 17327 17328 this.formattedDateTime = formattedDateTime; 17329 17330 if (!this._defaults.showTimepicker) { 17331 this.$input.val(this.formattedDate); 17332 } else if (this.$altInput && this._defaults.altFieldTimeOnly === true) { 17333 this.$altInput.val(this.formattedTime); 17334 this.$input.val(this.formattedDate); 17335 } else if (this.$altInput) { 17336 this.$altInput.val(formattedDateTime); 17337 this.$input.val(formattedDateTime); 17338 } else { 17339 this.$input.val(formattedDateTime); 17340 } 17341 17342 this.$input.trigger("change"); 17343 } 17344 17345 }); 17346 17347 $.fn.extend({ 17348 //######################################################################## 17349 // shorthand just to use timepicker.. 17350 //######################################################################## 17351 timepicker: function (o) { 17352 o = o || {}; 17353 var tmp_args = arguments; 17354 17355 if (typeof o == 'object') tmp_args[0] = $.extend(o, { timeOnly: true }); 17356 17357 return $(this).each(function () { 17358 $.fn.datetimepicker.apply($(this), tmp_args); 17359 }); 17360 }, 17361 17362 //######################################################################## 17363 // extend timepicker to datepicker 17364 //######################################################################## 17365 datetimepicker: function (o) { 17366 o = o || {}; 17367 var $input = this, 17368 tmp_args = arguments; 17369 17370 if (typeof (o) == 'string') { 17371 if (o == 'getDate') 17372 return $.fn.datepicker.apply($(this[0]), tmp_args); 17373 else 17374 return this.each(function () { 17375 var $t = $(this); 17376 $t.datepicker.apply($t, tmp_args); 17377 }); 17378 } 17379 else 17380 return this.each(function () { 17381 var $t = $(this); 17382 $t.datepicker($.timepicker._newInst($t, o)._defaults); 17383 }); 17384 } 17385 }); 17386 17387 //######################################################################## 17388 // the bad hack :/ override datepicker so it doesnt close on select 17389 // inspired: http://stackoverflow.com/questions/1252512/jquery-datepicker-prevent-closing-picker-when-clicking-a-date/1762378#1762378 17390 //######################################################################## 17391 $.datepicker._base_selectDate = $.datepicker._selectDate; 17392 $.datepicker._selectDate = function (id, dateStr) { 17393 var inst = this._getInst($(id)[0]), 17394 tp_inst = this._get(inst, 'timepicker'); 17395 17396 if (tp_inst) { 17397 tp_inst._limitMinMaxDateTime(inst, true); 17398 inst.inline = inst.stay_open = true; 17399 //This way the onSelect handler called from calendarpicker get the full dateTime 17400 this._base_selectDate(id, dateStr); 17401 inst.inline = inst.stay_open = false; 17402 this._notifyChange(inst); 17403 this._updateDatepicker(inst); 17404 } 17405 else this._base_selectDate(id, dateStr); 17406 }; 17407 17408 //############################################################################################# 17409 // second bad hack :/ override datepicker so it triggers an event when changing the input field 17410 // and does not redraw the datepicker on every selectDate event 17411 //############################################################################################# 17412 $.datepicker._base_updateDatepicker = $.datepicker._updateDatepicker; 17413 $.datepicker._updateDatepicker = function (inst) { 17414 17415 // don't popup the datepicker if there is another instance already opened 17416 const input = inst.input[0]; 17417 if ($.datepicker._curInst && 17418 $.datepicker._curInst != inst && 17419 $.datepicker._datepickerShowing && 17420 $.datepicker._lastInput != input) { 17421 return; 17422 } 17423 17424 if (typeof (inst.stay_open) !== 'boolean' || inst.stay_open === false) { 17425 17426 this._base_updateDatepicker(inst); 17427 17428 // Reload the time control when changing something in the input text field. 17429 const tp_inst = this._get(inst, 'timepicker'); 17430 if (tp_inst) tp_inst._addTimePicker(inst); 17431 } 17432 }; 17433 17434 //####################################################################################### 17435 // third bad hack :/ override datepicker so it allows spaces and colon in the input field 17436 //####################################################################################### 17437 $.datepicker._base_doKeyPress = $.datepicker._doKeyPress; 17438 $.datepicker._doKeyPress = function (event) { 17439 const inst = $.datepicker._getInst(event.target), 17440 tp_inst = $.datepicker._get(inst, 'timepicker'); 17441 17442 if (tp_inst) { 17443 if ($.datepicker._get(inst, 'constrainInput')) { 17444 const ampm = tp_inst._defaults.ampm, 17445 dateChars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')), 17446 datetimeChars = tp_inst._defaults.timeFormat.toString() 17447 .replace(/[hms]/g, '') 17448 .replace(/TT/g, ampm ? 'APM' : '') 17449 .replace(/Tt/g, ampm ? 'AaPpMm' : '') 17450 .replace(/tT/g, ampm ? 'AaPpMm' : '') 17451 .replace(/T/g, ampm ? 'AP' : '') 17452 .replace(/tt/g, ampm ? 'apm' : '') 17453 .replace(/t/g, ampm ? 'ap' : '') + 17454 " " + 17455 tp_inst._defaults.separator + 17456 tp_inst._defaults.timeSuffix + 17457 (tp_inst._defaults.showTimezone ? tp_inst._defaults.timezoneList.join('') : '') + 17458 (tp_inst._defaults.amNames.join('')) + 17459 (tp_inst._defaults.pmNames.join('')) + 17460 dateChars, 17461 chr = String.fromCharCode(event.charCode === undefined ? event.keyCode : event.charCode); 17462 return event.ctrlKey || (chr < ' ' || !dateChars || datetimeChars.indexOf(chr) > -1); 17463 } 17464 } 17465 17466 return $.datepicker._base_doKeyPress(event); 17467 }; 17468 17469 //####################################################################################### 17470 // Override key up event to sync manual input changes. 17471 //####################################################################################### 17472 $.datepicker._base_doKeyUp = $.datepicker._doKeyUp; 17473 $.datepicker._doKeyUp = function (event) { 17474 const inst = $.datepicker._getInst(event.target), 17475 tp_inst = $.datepicker._get(inst, 'timepicker'); 17476 17477 if (tp_inst) { 17478 if (tp_inst._defaults.timeOnly && (inst.input.val() !=
17478inst.lastVal)) { 17479 try { 17480 $.datepicker._updateDatepicker(inst); 17481 } 17482 catch (err) { 17483 $.datepicker.log(err); 17484 } 17485 } 17486 } 17487 17488 return $.datepicker._base_doKeyUp(event); 17489 }; 17490 17491 //####################################################################################### 17492 // override "Today" button to also grab the time. 17493 //####################################################################################### 17494 $.datepicker._base_gotoToday = $.datepicker._gotoToday; 17495 $.datepicker._gotoToday = function (id) { 17496 var inst = this._getInst($(id)[0]), 17497 $dp = inst.dpDiv; 17498 this._base_gotoToday(id); 17499 var now = new Date(); 17500 var tp_inst = this._get(inst, 'timepicker'); 17501 if (tp_inst._defaults.showTimezone && tp_inst.timezone_select) { 17502 var tzoffset = now.getTimezoneOffset(); // If +0100, returns -60 17503 var tzsign = tzoffset > 0 ? '-' : '+'; 17504 tzoffset = Math.abs(tzoffset); 17505 var tzmin = tzoffset % 60 17506 tzoffset = tzsign + ('0' + (tzoffset - tzmin) / 60).slice(-2) + ('0' + tzmin).slice(-2); 17507 if (tp_inst._defaults.timezoneIso8609) 17508 tzoffset = tzoffset.substring(0, 3) + ':' + tzoffset.substring(3); 17509 tp_inst.timezone_select.val(tzoffset); 17510 } 17511 this._setTime(inst, now); 17512 $('.ui-datepicker-today', $dp).click(); 17513 }; 17514 17515 //####################################################################################### 17516 // Disable & enable the Time in the datetimepicker 17517 //####################################################################################### 17518 $.datepicker._disableTimepickerDatepicker = function (target, date, withDate) { 17519 var inst = this._getInst(target), 17520 tp_inst = this._get(inst, 'timepicker'); 17521 $(target).datepicker('getDate'); // Init selected[Year|Month|Day] 17522 if (tp_inst) { 17523 tp_inst._defaults.showTimepicker = false; 17524 tp_inst._updateDateTime(inst); 17525 } 17526 }; 17527 17528 $.datepicker._enableTimepickerDatepicker = function (target, date, withDate) { 17529 var inst = this._getInst(target), 17530 tp_inst = this._get(inst, 'timepicker'); 17531 $(target).datepicker('getDate'); // Init selected[Year|Month|Day] 17532 if (tp_inst) { 17533 tp_inst._defaults.showTimepicker = true; 17534 tp_inst._addTimePicker(inst); // Could be disabled on page load 17535 tp_inst._updateDateTime(inst); 17536 } 17537 }; 17538 17539 //####################################################################################### 17540 // Create our own set time function 17541 //####################################################################################### 17542 $.datepicker._setTime = function (inst, date) { 17543 var tp_inst = this._get(inst, 'timepicker'); 17544 if (tp_inst) { 17545 var defaults = tp_inst._defaults, 17546 // calling _setTime with no date sets time to defaults 17547 hour = date ? date.getHours() : defaults.hour, 17548 minute = date ? date.getMinutes() : defaults.minute, 17549 second = date ? date.getSeconds() : defaults.second, 17550 millisec = date ? date.getMilliseconds() : defaults.millisec; 17551 17552 //check if within min/max times.. 17553 if ((hour < defaults.hourMin || hour > defaults.hourMax) || (minute < defaults.minuteMin || minute > defaults.minuteMax) || (second < defaults.secondMin || second > defaults.secondMax) || (millisec < defaults.millisecMin || millisec > defaults.millisecMax)) { 17554 hour = defaults.hourMin; 17555 minute = defaults.minuteMin; 17556 second = defaults.secondMin; 17557 millisec = defaults.millisecMin; 17558 } 17559 17560 tp_inst.hour = hour; 17561 tp_inst.minute = minute; 17562 tp_inst.second = second; 17563 tp_inst.millisec = millisec; 17564 17565 tp_inst._onTimeChange(); 17566 tp_inst._updateDateTime(inst); 17567 } 17568 }; 17569 17570 //####################################################################################### 17571 // Create new public method to set only time, callable as $().datepicker('setTime', date) 17572 //####################################################################################### 17573 $.datepicker._setTimeDatepicker = function (target, date, withDate) { 17574 var inst = this._getInst(target), 17575 tp_inst = this._get(inst, 'timepicker'); 17576 17577 if (tp_inst) { 17578 this._setDateFromField(inst); 17579 var tp_date; 17580 if (date) { 17581 if (typeof date == "string") { 17582 tp_inst._parseTime(date, withDate); 17583 tp_date = new Date();
17584 tp_date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec); 17585 } 17586 else tp_date = new Date(date.getTime()); 17587 if (tp_date.toString() == 'Invalid Date') tp_date = undefined; 17588 this._setTime(inst, tp_date); 17589 } 17590 } 17591 17592 }; 17593 17594 //####################################################################################### 17595 // override setDate() to allow setting time too within Date object 17596 //####################################################################################### 17597 $.datepicker._base_setDateDatepicker = $.datepicker._setDateDatepicker; 17598 $.datepicker._setDateDatepicker = function (target, date) { 17599 const inst = this._getInst(target); 17600 const tp_date = (date instanceof Date) ? new Date(date.getTime()) : date; 17601 17602 this._updateDatepicker(inst); 17603 this._base_setDateDatepicker.apply(this, arguments); 17604 if ($(target).next().is('[placeholder=time]')) { 17605 this._setTimeDatepicker($(target).next().get(0), tp_date, true); 17606 } 17607 else { 17608 this._setTimeDatepicker(target, tp_date, true); 17609 } 17610 }; 17611 17612 //####################################################################################### 17613 // override getDate() to allow getting time too within Date object 17614 //####################################################################################### 17615 $.datepicker._base_getDateDatepicker = $.datepicker._getDateDatepicker; 17616 $.datepicker._getDateDatepicker = function (target, noDefault) { 17617 var inst = this._getInst(target), 17618 tp_inst = this._get(inst, 'timepicker'); 17619 17620 if (tp_inst) { 17621 this._setDateFromField(inst, noDefault); 17622 var date = this._getDate(inst); 17623 if (date && tp_inst._parseTime($(target).val(), tp_inst.timeOnly)) date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec); 17624 return date; 17625 } 17626 return this._base_getDateDatepicker(target, noDefault); 17627 }; 17628 17629 //####################################################################################### 17630 // override parseDate() because UI 1.8.14 throws an error about "Extra characters" 17631 // An option in datapicker to ignore extra format characters would be nicer. 17632 //####################################################################################### 17633 $.datepicker._base_parseDate = $.datepicker.parseDate; 17634 $.datepicker.parseDate = function (format, value, settings) { 17635 var date; 17636 try { 17637 date = this._base_parseDate(format, value, settings); 17638 } catch (err) { 17639 // Hack! The error message ends with a colon, a space, and 17640 // the "extra" characters. We rely on that instead of 17641 // attempting to perfectly reproduce the parsing algorithm. 17642 date = this._base_parseDate(format, value.substring(0, value.length - (err.length - err.indexOf(':') - 2)), settings); 17643 } 17644 return date; 17645 }; 17646 17647 //####################################################################################### 17648 // override formatDate to set date with time to the input 17649 //####################################################################################### 17650 $.datepicker._base_formatDate = $.datepicker._formatDate; 17651 $.datepicker._formatDate = function (inst, day, month, year) { 17652 var tp_inst = this._get(inst, 'timepicker'); 17653 if (tp_inst) { 17654 if (day) 17655 var b = this._base_formatDate(inst, day, month, year); 17656 tp_inst._updateDateTime(inst); 17657 return tp_inst.$input.val(); 17658 } 17659 return this._base_formatDate(inst); 17660 } 17661 17662 //####################################################################################### 17663 // override options setter to add time to maxDate(Time) and minDate(Time). MaxDate 17664 //####################################################################################### 17665 $.datepicker._base_optionDatepicker = $.datepicker._optionDatepicker; 17666 $.datepicker._optionDatepicker = function (target, name, value) { 17667 var inst = this._getInst(target), 17668 tp_inst = this._get(inst, 'timepicker'); 17669 if (tp_inst) { 17670 var min, max, onselect; 17671 if (typeof name == 'string') { // if min/max was set with the string 17672 if (name === 'minDate' || name === 'minDateTime') 17673 min = value; 17674 else if (name === 'maxDate' || name === 'maxDateTime') 17675 max = value; 17676 else if (name === 'onSelect') 17677 onselect = value; 17678 } else if (typeof name == 'object') { //if min/max was set with the JSON 17679 if (name.minDate) 17680 min = name.minDate; 17681 else if (name.minDateTime) 17682 min = name.minDateTime; 17683 else if (name.maxDate) 17684 max = name.maxDate; 17685 else if (name.maxDateTime) 17686 max = name.maxDateTime; 17687 } 17688 if (min) { //if min was set 17689 if (min == 0) 17690 min = new Date(); 17691 else 17692 min = new Date(min); 17693 17694 tp_inst._defaults.minDate = min; 17695 tp_inst._defaults.minDateTime = min; 17696 } else if (max) { //if max was set 17697 if (max == 0) 17698 max = new Date(); 17699 else 17700 max = new Date(max); 17701 tp_inst._defaults.maxDate = max; 17702 tp_inst._defaults.maxDateTime = max; 17703 } 17704 else if (onselect) 17705 tp_inst._defaults.onSelect = onselect; 17706 } 17707 if (value === undefined) 17708 return this._base_optionDatepicker(target, name); 17709 return this._base_optionDatepicker(target, name, value); 17710 }; 17711 17712 //####################################################################################### 17713 // jQuery extend now ignores nulls! 17714 //####################################################################################### 17715 function extendRemove(target, props) { 17716 $.extend(target, props); 17717 for (var name in props) 17718 if (props[name] === null || props[name] === undefined) 17719 target[name] = props[name]; 17720 return target; 17721 } 17722 17723 $.timepicker = new Timepicker(); // singleton instance 17724 $.timepicker.version = "0.9.8"; 17725 17726})(jQuery); 17727 17728 17729(function($) { 17730 var wrapDateOrTime = function (args) { 17731 var context = this; 17732 var $hidden = $(this); 17733 $hidden.wrap('<div/>'); 17734 var $wrapper = $(this).parent(); 17735 $wrapper.attr('style', $(this).attr('style')); 17736 if (args.width) { 17737 $wrapper.css({ width: args.width }); 17738 } 17739 17740 let formattedValue = $(this).val(); 17741 17742 if (formattedValue) { 17743 formattedValue = moment(formattedValue, args.momentDateFormat).format(args.momentDateFormat); 17744 } 17745 17746 const minDateAttr = $(this).attr('min-date'); 17747 const maxDateAttr = $(this).attr('max-date'); 17748 const minDate = !!minDateAttr ? new Date(minDateAttr) : undefined; 17749 const maxDate = !!maxDateAttr ? new Date(maxDateAttr) : undefined; 17750 17751 var $input = $(`<input class="${$(this).attr('class') || ''}" type="text" value="${formattedValue}" min-date="{${$(this).attr('min-date') || ''}" placeholder="${$(this).attr('placeholder') || ''}" style="width: 100%;" ${context.prop('disabled') === true ? 'disabled' : 'not-disabled'}>`); 17752 $input.on('change', function () { 17753 let newValue = $(this).val(); 17754 17755 if (newValue !== '') { 17756 if (!newValue.match(/[\-/][0-9]{1,2}[\-/]/g)) { 17757 newValue = ''; 17758 } 17759 17760 if (new Date(newValue) && new Date(newValue) < minDate) { 17761 newValue = minDate; 17762 } 17763 else if (new Date(newValue) && new Date(newValue) > maxDate) { 17764 newValue = maxDate; 17765 } 17766 17767 newValue = moment(newValue).format('MM/DD/YYYY'); 17768 17769 if (newValue === 'Invalid date') { 17770 newValue = ''; 17771 } 17772 17773 $input.val(newValue); 17774 } 17775 17776 if ($hidden.val() !== newValue) { 17777 $hidden.val(newValue); 17778 if (args.onClientChange) { 17779 args.onClientChange.apply(context, [newValue]); 17780 } 17781 } 17782 }); 17783 17784 $hidden.css({ display: 'none' }); 17785 $wrapper.append($input); 17786 17787 return $input; 17788 }; 17789 17790 $.fn.smptimepicker = function (args) { 17791 const opts = args ? { ...args } : {}; 17792 17793 if (!opts.dateFormat) { 17794 opts.momentDateFormat = 'h:mm a'; 17795 opts.dateFormat = 'h:mm a'; 17796 } 17797 17798 var $input = wrapDateOrTime.apply(this, [opts]); 17799 var $hidden = $(this); 17800 17801 // Override the date-oriented change handler with a time-appropriate one 17802 $input.off('change').on('change', function () { 17803 let newValue = $(this).val(); 17804 17805 if (newValue !== '') { 17806 var parsed = moment(newValue, ['h:mm a', 'h:mm A', 'HH:mm', 'h:mma', 'h:mmA'], true); 17807 if (parsed.isValid()) {
17808 newValue = parsed.format(opts.momentDateFormat); 17809 } else { 17810 newValue = ''; 17811 } 17812 $input.val(newValue); 17813 } 17814 17815 if ($hidden.val() !== newValue) { 17816 $hidden.val(newValue); 17817 if (opts.onClientChange) { 17818 opts.onClientChange.apply($hidden, [newValue]); 17819 } 17820 } 17821 }); 17822 17823 $input.timepicker(opts); 17824 }; 17825 17826 $.fn.smpdatepicker = function (args) { 17827 const opts = args ? { ...args } : {}; 17828 17829 if (!opts.dateFormat) { 17830 opts.momentDateFormat = 'MM/DD/YYYY'; 17831 opts.dateFormat = 'mm/dd/yy'; 17832 } 17833 17834 const $input = wrapDateOrTime.apply(this, [opts]); 17835 if (opts.hidePopup) { 17836 return; 17837 } 17838 $input.datepicker(opts); 17839 }; 17840 17841 $.fn.smpdatetimepicker = function(args) { 17842 const opts = args ? { ...args } : {}; 17843 17844 var context = this; 17845 var $hidden = $(this); 17846 $hidden.css({ display: 'none' }); 17847 $hidden.wrap('<div class="smpdatetimewrapper" />'); 17848 var $wrapper = $(this).parent(); 17849 if(opts.width) { 17850 $wrapper.css({ width: opts.width }); 17851 } 17852 var $date = $('<input type="text" placeholder="date" value="' 17853 + ($(this).val() ? moment($(this).val()).format('MM/DD/YYYY') : '') + '" ' 17854 + (context.prop('disabled') === true ? 'disabled' : 'not-disabled') 17855 + (context.is('[id]') ? ' id="' + context.attr('id') + '_date"': '') + '>'); 17856 var $time = $('<input type="text" placeholder="time" value="' 17857 + ($(this).val() ? moment($(this).val()).format('h:mm a') : '') + '" ' 17858 + (context.prop('disabled') === true ? 'disabled' : 'not-disabled') 17859 + (context.is('[id]') ? ' id="' + context.attr('id') + '_time"' : '') + '>'); 17860 $wrapper.append($date).append($time); 17861 17862 var updateHiddenValue = function () { 17863 var newValue = $date.val() + ' ' + $time.val(); 17864 if (newValue !== $hidden.val()) { 17865 $hidden.val(newValue).trigger('change'); 17866 if (opts.onClientChange) { 17867 opts.onClientChange.apply(context, [newValue]); 17868 } 17869 } 17870 }; 17871 $($date).on('change', updateHiddenValue); 17872 $($time).on('change', updateHiddenValue); 17873 17874 opts.timeOnlyTitle = 'Enter Time'; 17875 $date.datepicker(opts); 17876 $time.timepicker(opts); 17877 }; 17878})(jQuery); 17879 17880 17881; 17882////pf: javascript/jquery-mask.js 17883/* @version 1.0.4 $Revision: 52 $ 17884* The MIT License 17885* Copyright (c) 2008 Fabio M. Costa http://www.meiocodigo.com 17886*/ 17887(function (B) { var A = (window.orientation != undefined); B.extend({ mask: { rules: { "z": /[a-z]/, "Z": /[A-Z]/, "a": /[a-zA-Z]/, "*": /[0-9a-zA-Z]/, "@": /[0-9a-zA-ZçÃâ¡Ã¡à ãéèÃÂìóòõúùü]/ }, fixedChars: "[(),.:/ -]", keyRepresentation: { 8: "backspace", 9: "tab", 13: "enter", 16: "shift", 17: "control", 18: "alt", 27: "esc", 33: "page up", 34: "page down", 35: "end", 36: "home", 37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "delete", 116: "f5", 224: "command" }, iphoneKeyRepresentation: { 10: "go", 127: "delete" }, signals: { "+": "", "-": "-" }, options: { attr: "alt", mask: null, type: "fixed", defaultValue: "", signal: false, onInvalid: function () { }, onValid: function () { }, onOverflow: function () { } }, masks: { "phone": { mask: "(99) 9999-9999" }, "phone-us": { mask: "(999) 9999-9999" }, "cpf": { mask: "999.999.999-99" }, "cnpj": { mask: "99.999.999/9999-99" }, "date": { mask: "39/19/9999" }, "date-us": { mask: "19/39/9999" }, "cep": { mask: "99999-999" }, "time": { mask: "29:59" }, "cc": { mask: "9999 9999 9999 9999" }, "integer": { mask: "999.999.999.999", type: "reverse" }, "decimal": { mask: "99,999.999.999.999", type: "reverse", defaultValue: "000" }, "decimal-us": { mask: "99.999,999,999,999", type: "reverse", defaultValue: "000" }, "signed-decimal": { mask: "99,999.999.999.999", type: "reverse", defaultValue: "+000" }, "signed-decimal-us": { mask: "99,999.999.999.999", type: "reverse", defaultValue: "+000"} }, init: function () { if (!this.hasInit) { var C = this, D, E = (A) ? this.iphoneKeyRepresentation : this.keyRepresentation; this.ignore = false; this.fixedCharsReg = new RegExp(this.fixedChars); this.fixedCharsRegG = new RegExp(this.fixedChars, "g"); for (D = 0; D <= 9; D++) { this.rules[D] = new RegExp("[0-" + D + "]") } this.keyRep = E; this.ignoreKeys = []; B.each(E, function (F) { C.ignoreKeys.push(parseInt(F)) }); this.hasInit = true } }, set: function (G, D) { var C = this, E = B(G), F = "maxLength"; this.init(); return E.each(function () { var N = B(this), O = B.extend({}, C.options), M = N.attr(O.attr), H = "", J = C.__getPasteEvent(); H = (typeof D == "string") ? D : (M != "") ? M : null; if (H) { O.mask = H } if (C.masks[H]) { O = B.extend(O, C.masks[H]) } if (typeof D == "object") { O = B.extend(O, D) } if (B.metadata) { O = B.extend(O, N.metadata()) } if (O.mask != null) { if (N.data("mask")) { C.unset(N) } var I = O.defaultValue, L = N.attr(F), K = (O.type == "reverse"); O = B.extend({}, O, { maxlength: L, maskArray: O.mask.split(""), maskNonFixedCharsArray: O.mask.replace(C.fixedCharsRegG, "").split("") }); if (K) { N.css("text-align", "right") } if (N.val() != "") { N.val(C.string(N.val(), O)) } else { if (I != "") { N.val(C.string(I, O)) } } N.data("mask", O); N.removeAttr(F); N.bind("keydown", { func: C._keyDown, thisObj: C }, C._onMask).bind("keyup", { func: C._keyUp, thisObj: C }, C._onMask).bind("keypress", { func: C._keyPress, thisObj: C }, C._onMask).bind(J, { func: C._paste, thisObj: C }, C._delayedOnMask) } }) }, unset: function (D) { var C = B(D), E = this; return C.each(function () { var H = B(this); if (H.data("mask")) { var F = H.data("mask").maxlength, G = E.__getPasteEvent(); if (F != -1) { H.attr("maxLength", F) }
17887 H.unbind("keydown", E._onMask).unbind("keypress", E._onMask).unbind("keyup", E._onMask).unbind(G, E._delayedOnMask).removeData("mask") } }) }, string: function (F, C) { this.init(); var E = {}; if (typeof F != "string") { F = String(F) } switch (typeof C) { case "string": if (this.masks[C]) { E = B.extend(E, this.masks[C]) } else { E.mask = C } break; case "object": E = C } if ((E.type == "reverse") && E.defaultValue) { if (typeof this.signals[E.defaultValue.charAt(0)] != "undefined") { var D = F.charAt(0); E.signal = (typeof this.signals[D] != "undefined") ? this.signals[D] : this.signals[E.defaultValue.charAt(0)]; E.defaultValue = E.defaultValue.substring(1) } } return this.__maskArray(F.split(""), E.mask.replace(this.fixedCharsRegG, "").split(""), E.mask.split(""), E.type, E.defaultValue, E.signal) }, unmaskedVal: function (C) { return B(C).val().replace(B.mask.fixedCharsRegG, "") }, _onMask: function (C) { var E = C.data.thisObj, D = {}; D._this = C.target; D.$this = B(D._this); if (D.$this.attr("readonly")) { return true } D.value = D.$this.val(); D.nKey = E.__getKeyNumber(C); D.range = E.__getRange(D._this); D.valueArray = D.value.split(""); D.data = D.$this.data("mask"); D[D.data.type] = true; return C.data.func.call(E, C, D) }, _delayedOnMask: function (C) { C.type = "paste"; setTimeout(function () { C.data.thisObj._onMask(C) }, 1) }, _keyDown: function (D, E) { this.ignore = (B.inArray(E.nKey, this.ignoreKeys) > -1); if (this.ignore) { var C = this.keyRep[E.nKey]; E.data.onValid.call(E._this, C ? C : "", E.nKey) } return A ? this._keyPress(D, E) : true }, _keyUp: function (C, D) { if (D.nKey == 9 && (false)) { return true } return (!D.infinite) ? this._paste(C, D) : true }, _paste: function (D, E) { if (E.reverse) { this.__changeSignal(D.type, E) } var C = this.__maskArray(E.valueArray, E.data.maskNonFixedCharsArray, E.data.maskArray, E.data.type, E.data.defaultValue, E.data.signal); E.$this.val(C); if (!E.reverse && E.data.defaultValue.length && (E.range.start == E.range.end)) { this.__setRange(E._this, E.range.start, E.range.end) } if ((false) && !E.reverse) { this.__setRange(E._this, E.range.start, E.range.end) } return true }, _keyPress: function (J, C) { if (this.ignore || J.ctrlKey || J.metaKey || J.altKey) { return true } if (C.reverse) { this.__changeSignal(J.type, C) } var K = String.fromCharCode(C.nKey), M = C.range.start, G = C.value, E = C.data.maskArray; if (C.reverse) { var F = G.substr(0, M), I = G.substr(C.range.end, G.length); G = (F + K + I); if (C.data.signal && (M - C.data.signal.length > 0)) { M -= C.data.signal.length } } var L = G.replace(this.fixedCharsRegG, "").split(""), D = this.__extraPositionsTill(M, E); C.rsEp = M + D; if (C.infinite) { C.rsEp = 0 } if (!this.rules[E[C.rsEp]]) { C.data.onOverflow.call(C._this, K, C.nKey); return false } else { if (!this.rules[E[C.rsEp]].test(K)) { C.data.onInvalid.call(C._this, K, C.nKey); return false } else { C.data.onValid.call(C._this, K, C.nKey) } } var H = this.__maskArray(L, C.data.maskNonFixedCharsArray, E, C.data.type, C.data.defaultValue, C.data.signal, D); C.$this.val(H); return (C.reverse) ? this._keyPressReverse(J, C) : (C.fixed) ? this._keyPressFixed(J, C) : true }, _keyPressFixed: function (C, D) { if (D.range.start == D.range.end) { if ((D.rsEp == 0 && D.value.length == 0) || D.rsEp < D.value.length) { this.__setRange(D._this, D.rsEp, D.rsEp + 1) } } else { this.__setRange(D._this, D.range.start, D.range.end) } return true }, _keyPressReverse: function (C, D) { if (false && ((D.rangeStart == 0 && D.range.end == 0) || D.rangeStart != D.range.end)) { this.__setRange(D._this, D.value.length) } return false }, __changeSignal: function (D, E) { if (E.data.signal !== false) { var C = (D == "paste") ? E.value.charAt(0) : String.fromCharCode(E.nKey); if (this.signals && (typeof this.signals[C] != "undefined")) { E.data.signal = this.signals[C] } } }, __getPasteEvent: function () { return (false) ? "input" : "paste" }, __getKeyNumber: function (C) { return (C.charCode || C.keyCode || C.which) }, __maskArray: function (H, G, D, F, C, I, E) { if (F == "reverse") { H.reverse() } H = this.__removeInvalidChars(H, G); if (C) { H = this.__applyDefaultValue.call(H, C) } H = this.__applyMask(H, D, E); switch (F) { case "reverse": H.reverse(); return (I || "") + H.join("").substring(H.length - D.length); case "infinite": return H.join(""); default: return H.join("").substring(0, D.length) } return "" }, __applyDefaultValue: function (E) { var C = E.length, D = this.length, F; for (F = D - 1; F >= 0; F--) { if (this[F] == E.charAt(0)) { this.pop() } else { break } } for (F = 0; F < C; F++) { if (!this[F]) { this[F] = E.charAt(F) } } return this }, __removeInvalidChars: function (E, D) { for (var C = 0; C < E.length; C++) { if (D[C] && this.rules[D[C]] && !this.rules[D[C]].test(E[C])) { E.splice(C, 1); C-- } } return E }, __applyMask: function (E, C, F) { if (typeof F == "undefined") { F = 0 } for (var D = 0; D < E.length + F; D++) { if (C[D] && this.fixedCharsReg.test(C[D])) { E.splice(D, 0, C[D]) } } return E }, __extraPositionsTill: function (E, C) { var D = 0; while (this.fixedCharsReg.test(C[E])) { E++; D++ } return D }, __setRange: function (E, F, C) { if (typeof C == "undefined") { C = F }
17887 if (E.setSelectionRange) { E.setSelectionRange(F, C) } else { var D = E.createTextRange(); D.collapse(); D.moveStart("character", F); D.moveEnd("character", C - F); D.select() } }, __getRange: function (D) { if (true) { return { start: D.selectionStart, end: D.selectionEnd} } var E = { start: 0, end: 0 }, C = document.selection.createRange(); E.start = 0 - C.duplicate().moveStart("character", -100000); E.end = E.start + C.text.length; return E } } }); B.fn.extend({ setMask: function (C) { return B.mask.set(this, C) }, unsetMask: function () { return B.mask.unset(this) }, unmaskedVal: function () { return B.mask.unmaskedVal(this[0]) } }) })(jQuery) 17888 17889 17890; 17891////pf: javascript/jquery-growfield.js 17892eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('(c($){$.G.2e=c(u){6.I(c(){6.y=b;L a=$(6);8(6.2f.K()!=\'2b\')e f;8(!u)u={};L C=6;6.7={k:(A(u.k)!=\'P\'?u.k:b),N:(A(u.N)!=\'P\'?u.N:b),F:(A(u.1P)!=\'P\'?u.1P:0),1i:(u.1i||1h),13:(u.13||1h),m:(u.m||f),s:(u.s||f),D:(u.D||f),Q:0,17:f,14:f,l:1h,X:0,18:2s,1w:15,16:f,O:f,1O:f};6.1F=c(){8(6.7.1i)6.1v=6.7.1i;8(6.7.13)6.1u=6.7.13;6.7.Q=a.H(0).E;8(A(a.r(\'B\'))!=\'P\')6.7.k=v(a.r(\'B\'));8(A(a.r(\'N\'))!=\'P\')6.7.N=v(a.r(\'N\'));8(A(a.r(\'m\'))!=\'P\')6.7.m=v(a.r(\'m\'));8(A(a.r(\'s\'))!=\'P\')6.7.s=v(a.r(\'s\'));8(A(a.r(\'D\'))!=\'P\')6.7.D=v(a.r(\'D\'));8(A(a.r(\'18\'))!=\'P\')6.7.18=v(a.r(\'18\'));8(!6.7.m)6.7.m=v(a.o(\'m-R\'));8(!6.7.m)6.7.m=6.7.Q;8(!6.7.s)6.7.s=v(a.o(\'s-R\'));6.7.O=($.t.Z&&$.t.2q<9.5);8(6.7.D){6.7.D=f;6.1t(b)}8(6.7.k){8(6.7.Q==0){a.12(\'M.1M\',6.1L)}z{6.7.k=f;6.1j(b)}}z 6.1c(b);e b};6.1L=c(){6.7.Q=a.H(0).E;8(!6.7.Q)e b;8(!6.7.m)6.7.m=6.7.Q;a.V(\'.1M\');6.7.k=f;6.1j(b);a.U();e b};6.1c=c(w){8(w){8(6.7.14)e f;a.12(($.t.1m?\'M\':\'1I\')+\'.B\',c(j){8(!j.1V||$.1Y(j.1N,[1G,23])==-1)e b;a[j.1N==1G?\'1K\':\'1J\'](f,j);8($.t.Z)a.U();8($.t.1m||$.t.Z)e f;e b});6.7.14=b}z{8(!6.7.14)e f;a.V(($.t.1m?\'M\':\'1I\')+\'.B\');6.7.14=f}};6.1j=c(w){8($.t.Z||w){a.o(\'x\',\'T\');8($.t.Z&&a.r(\'1Q\')&&a.r(\'1Q\').20(\'1T\')==-1)a.o(\'1T\',\'1Z 1W #1X\')}8(w){8(6.7.k)e f;6.1c(f);6.1y();8(6.7.1O){6.y=f;e f}a.o(\'x\',\'T\');a.12(\'M.B\',c(j){8(!a.q())6.S(6.7.m,j);z e 6.S(6.1x(),j)});8(a.q())a.M();$(1g).12(\'1C.B\',c(j){C.7.l.1l(a.1l())});6.7.k=b}z{8(!6.7.k)e f;6.7.l.1z();6.7.l=1h;a.V(\'M.B\');$(1g).V(\'1C.B\');a.o(\'x\',\'k\');6.7.k=f;6.1c(b)}e b};6.1t=c(w){8(w){8(6.7.D)e f;6.7.D=b;a.12(\'U.B\',c(j,1D){8(!6.7.k||1D||!a.q())e b;z e 6.S(6.1x(),j)});a.12(\'1A.B\',c(j){e 6.7.k?6.S(6.7.m,j):b})}z{8(!6.7.D)e f;6.7.D=f;a.V(\'U.B\').V(\'1A.B\');a.M()}};6.S=c(p,j){8(6.7.17)e b;8(!j)j={};6.1H(j);L W=a.o(\'x\');8(6.7.s>0&&p>=6.7.s){p=6.7.s;8(W==\'T\'){a.o(\'x\',\'k\');8(j.1b==\'M\')a.U();8(j.1b==\'U\'&&6.7.N&&6.7.k)a.21(\'U\',b)}}z 8(W==\'k\'&&6.7.k){a.o(\'x\',\'T\');8(j.1b==\'M\')a.U()}8(6.7.m>0&&p<=6.7.m)p=6.7.m;8(p==a.H(0).E){6.7.17=f;e b}e 6.1B(a.H(0).E,p,j,W)};6.1B=c(J,p,j,W){8(!6.7.N||(W==\'k\'&&6.7.k)||j.1b==\'22\'){a.R(p);e 6.1f(j)}6.7.X=1p.2y((6.7.18/6.7.1w)*(p<J?-1:1));6.1o(J,p);e b};6.1o=c(J,p){8(C.7.X==0)e C.1f();C.7.X+=(C.7.X>0?-1:1);8(1p.2p(p-J)<3){a.R(p);e C.1f()}J=C.7.X==0?p:J+1p.2o((p-J)/2);a.R(J);C.7.16=1g.2n(c(){C.1o(J,p)},C.7.1w)};6.1x=c(){L q=a.q();8($.t.1a&&q.2l(-2)=="\\n\\n")q=q.2m(0,q.2r-2)+"\\1S";8($.t.1a)6.7.l.q(\'\');6.7.l.q(q);8(6.7.O)6.7.l.o(\'x\',\'T\').o(\'x\',\'k\');L d=6.7.l.H(0);8(6.7.O)e d.1k+6.7.F;8((d.1d+($.t.1a?1:0))>d.1k){e d.1d+(d.E-d.1k)+6.7.F+($.t.1a?6.7.F:0)}z{8(!a.q())e 6.7.m;z e d.E+6.7.F}};6.1y=c(){8(6.7.l){6.7.l.1z();6.7.l=f}L i=b;L 1e=f;2x(i){6.7.l=a.2w().o({2t:\'2u\',2v:-1R,2k:0,2j:\'T\',1l:a.H(0).24}).r(\'2a\',-1R);8(6.7.O){6.7.l.o({x:\'k\',R:\'k\'});L 19=a.o(\'19\');8((19&&19<4)||1e)6.7.l.o({19:\'27\'})}6.7.l.H(0).y=f;a.13(6.7.l);6.7.l.q(\'\').R(10);6.7.l.q("11");8(6.7.O)6.7.l.o(\'x\',\'T\').o(\'x\',\'k\');L 1U=6.7.l.H(0).1d;6.7.l.q("11\\1S");8(6.7.O)6.7.l.o(\'x\',\'T\').o(\'x\',\'k\');L 1E=6.7.l.H(0).1d;8(!6.7.F){6.7.F=1E-1U;8($.t.Z&&!6.7.O)6.7.F+=6.7.l.H(0).E-6.7.l.R()}8(6.7.O&&6.7.F==0){8(1e)i=f;z{1e=b;6.7.l.1z();26}}z i=f}};6.1H=c(j){6.7.17=b;6.1v(j)};6.1f=c(j){8(6.7.16){1g.2c(6.7.16);6.7.16=f}6.7.17=f;6.1u(j);e b};6.1v=c(){};6.1u=c(){};$(c(){C.1F()})})};$.G.1J=c(Y,j){6.I(c(){8(!6.y||6.7.k)e b;6.S(6.E+(Y?v(Y):6.7.F),j)})};$.G.1K=c(Y,j){6.I(c(){8(!6.y||6.7.k)e b;6.S(6.E-(Y?v(Y):6.7.F),j)})};$.G.2h=c(g){8(g&&g!=b&&g!=f&&g.K()!=\'w\'&&g.K()!=\'1r\')1s(g);8(g&&A(g)==\'1n\')g=g.K()==\'w\'?b:f;6.I(c(){8(!6.y)e b;6.1j(g)})};$.G.2i=c(g){8(g&&g!=b&&g!=f&&g.K()!=\'w\'&&g.K()!=\'1r\')1s(g);8(g&&A(g)==\'1n\')g=g.K()==\'w\'?b:f;6.I(c(){8(!6.y)e b;6.7.N=g})};$.G.1q=c(h){6.I(c(){8(!6.y)e b;6.S(h)})};$.G.2g=c(h){6.I(c(){8(!6.y)e b;h=v(h);8(h<10&&6.7.Q)h=6.7.Q;8(h<10)e b;6.7.m=v(h);8(6.E<6.7.m)$(6).1q(6.7.m)})};
17892$.G.2d=c(h){6.I(c(){8(!6.y)e b;6.7.s=v(h);8(6.E>6.7.s)$(6).1q(6.7.s)})};$.G.29=c(g){8(g&&g!=b&&g!=f&&g.K()!=\'w\'&&g.K()!=\'1r\')1s(g);8(g&&A(g)==\'1n\')g=g.K()==\'w\'?b:f;6.I(c(){8(!6.y)e b;6.1t(g)})};$.G.25=c(){6.I(c(){8(!6.y)e b;6.1y()})}})(28);',62,159,'||||||this|gf|if||txt|true|function||return|false|bool|||event|auto|dummy|min||css|to|val|attr|max|browser|options|parseInt|on|overflow|_growField|else|typeof|autogrow|th|restore|offsetHeight|hOffset|fn|get|each|from|toLowerCase|var|keyup|animate|opera9|undefined|initialH|height|_changeSize|hidden|focus|unbind|ovr|queue|step|opera|||bind|after|keysEnabled||timeout|busy|speed|padding|safari|type|_toggleKeys|scrollHeight|tryPadding|_growAfter|window|null|before|_toggleAuto|clientHeight|width|msie|string|_timeout|Math|growTo|off|delete|_toggleRestore|_growCallbackAfter|_growCallbackBefore|ms|_textHeight|_createDummy|remove|blur|_animate|resize|noChange|s2|_growInit|38|_growBefore|keydown|increase|decrease|_afterShowInit|growinit|keyCode|impossible|offset|style|9999|n11|border|s1|ctrlKey|solid|ccc|inArray|1px|indexOf|trigger|init|40|offsetWidth|growRenewDummy|continue|4px|jQuery|growToggleRestore|tabindex|textarea|clearTimeout|growSetMax|growfield|tagName|growSetMin|growToggleAuto|growToggleAnimation|visibility|top|substr|substring|setTimeout|ceil|abs|version|length|300|position|absolute|left|clone|while|floor'.split('|'),0,{})) 17893 17894 17895; 17896////pf: javascript/jquery-fieldselection.js 17897/* 17898* jQuery plugin: fieldSelection - v0.1.0 - last change: 2006-12-16 17899* (c) 2006 Alex Brem <[email protected]> - http://blog.0xab.cd 17900*/ 17901 17902; (function($) { 17903 17904 var fieldSelection = { 17905 17906 getSelection: function() { 17907 17908 var e = this.jquery ? this[0] : this; 17909 17910 return ( 17911 17912 /* mozilla / dom 3.0 */ 17913 ('selectionStart' in e && function() { 17914 var l = e.selectionEnd - e.selectionStart; 17915 return { start: e.selectionStart, end: e.selectionEnd, length: l, text: e.value.substr(e.selectionStart, l) }; 17916 }) || 17917 17918 /* exploder */ 17919 (document.selection && function() { 17920 17921 e.focus(); 17922 17923 var r = document.selection.createRange(); 17924 if (r == null) { 17925 return { start: 0, end: e.value.length, length: 0 } 17926 } 17927 17928 var re = e.createTextRange(); 17929 var rc = re.duplicate(); 17930 re.moveToBookmark(r.getBookmark()); 17931 rc.setEndPoint('EndToStart', re); 17932 17933 return { start: rc.text.length, end: rc.text.length + r.text.length, length: r.text.length, text: r.text }; 17934 }) || 17935 17936 /* browser not supported */ 17937 function() { 17938 return { start: 0, end: e.value.length, length: 0 }; 17939 } 17940 17941 )(); 17942 17943 }, 17944 17945 replaceSelection: function() { 17946 17947 var e = this.jquery ? this[0] : this; 17948 var text = arguments[0] || ''; 17949 17950 return ( 17951 17952 /* mozilla / dom 3.0 */ 17953 ('selectionStart' in e && function() { 17954 e.value = e.value.substr(0, e.selectionStart) + text + e.value.substr(e.selectionEnd, e.value.length); 17955 return this; 17956 }) || 17957 17958 /* exploder */ 17959 (document.selection && function() { 17960 e.focus(); 17961 document.selection.createRange().text = text; 17962 return this; 17963 }) || 17964 17965 /* browser not supported */ 17966 function() { 17967 e.value += text; 17968 return this; 17969 } 17970 17971 )(); 17972 17973 } 17974 17975 }; 17976 17977 jQuery.each(fieldSelection, function(i) { jQuery.fn[i] = this; }); 17978 17979})(); 17980 17981 17982; 17983////pf: javascript/autosuggest/jquery.autoSuggest.js 17984 /* 17985 * AutoSuggest 17986 * Copyright 2012 Jarrett Widman 17987 * www.24m2.com 17988 * 17989 * Version 1.5 - Updated: January 2011 17990 * 17991 * Based On: 17992 * AutoSuggest 17993 * Copyright 2009-2010 Drew Wilson 17994 * www.drewwilson.com 17995 * code.drewwilson.com/entry/autosuggest-jquery-plugin 17996 * 17997 * Version 1.4 - Updated: Mar. 23, 2010 17998 * 17999 * This Plug-In will auto-complete or auto-suggest completed search queries 18000 * for you as you type. You can add multiple selections and remove them on 18001 * the fly. It supports keybord navigation (UP + DOWN + RETURN), as well 18002 * as multiple AutoSuggest fields on the same page. 18003 * 18004 * Inspied by the Autocomplete plugin by: J�rn Zaefferer 18005 * and the Facelist plugin by: Ian Tearle (iantearle.com) 18006 * 18007 * This AutoSuggest jQuery plug-in is dual licensed under the MIT and GPL licenses: 18008 * http://www.opensource.org/licenses/mit-license.php 18009 * http://www.gnu.org/licenses/gpl.html 18010 */ 18011 18012( function ( $ ) 18013{ 18014 $.fn.autoSuggest = function ( data, options ) 18015 { 18016 const defaults = { 18017 asHtmlID: false, 18018 asHtmlName: false, 18019 startText: "Search", 18020 startAgainText: "Search Again", 18021 emptyText: "No Results Found", 18022 preFill: {}, 18023 limitText: "No More Selections Are Allowed", 18024 selectedItemProp: "name", //name of object property 18025 selectedValuesProp: "value", //name of object property 18026 selectedExtraProp: "extraJSON", //comma separated list of object property names 18027 searchObjProps: "name", //comma separated list of object property names 18028 allowShowAtTop: true, 18029 noDuplicates: true, //when true, already selected items won't appear in dropdown 18030 resultsOpenEvent: function (elem) { }, 18031 queryParam: "q", 18032 retrieveLimit: false, //number for 'limit' param on ajax request 18033 extraParams: "", 18034 GetExtraParams: () => "", 18035 matchCase: false, 18036 minChars: 2, 18037 keyDelay: 175, 18038 resultsHighlight: true,
18039 newTextAllowed: false, 18040 allowCommaInNewText: false, 18041 keepOpenUntilMaxSelections: false, 18042 clientNewTextAdded: function ( data ) { }, 18043 neverSubmit: true, 18044 selectionLimit: 1, 18045 showResultList: true, 18046 start: function () { }, 18047 selectionClick: function ( elem ) { }, 18048 selectionAdded: function ( elem ) { }, 18049 selectionRemoved: function (elem) { }, 18050 selectionChanged: function (elem) { }, 18051 formatList: false, //callback function 18052 beforeRetrieve: function ( string ) { return string; }, 18053 retrieveComplete: function ( data ) { return data; }, 18054 resultClick: function ( data ) { }, 18055 resultsComplete: function () { }, 18056 delimeter: "|||", 18057 width: "100%", 18058 useCustomStyle: false 18059 }; 18060 18061 let aborter = new AbortController(); 18062 var d_type = "object"; 18063 var d_count = 0; 18064 var lastKeyPressCode = -1; 18065 18066 if ( typeof data == "string" ) 18067 { 18068 d_type = "string"; 18069 var req_string = data; 18070 } else 18071 { 18072 var org_data = data; 18073 for ( k in data ) if ( data.hasOwnProperty( k ) ) d_count++; 18074 } 18075 if ( ( d_type == "object" && d_count > 0 ) || d_type == "string" ) 18076 { 18077 return this.each(function (x) { 18078 18079 if (this.bound) { //prevent duplicate initialization 18080 return; 18081 } 18082 18083 let opts = $.extend({}, defaults, options); 18084 const extraSelected = []; 18085 let x_id = null; 18086 18087 if (!opts.asHtmlID) { 18088 x = x + "" + Math.floor(Math.random() * 100000); //this ensures there will be unique IDs on the page if autoSuggest() is called multiple times 18089 x_id = "as-input-" + x; 18090 } else { 18091 x = opts.asHtmlID; 18092 x_id = x; 18093 } 18094 18095 let x_name = opts.asHtmlName || x_id; 18096 18097 const $wrapper = $(this).wrap('<div class="as-container"/>'); 18098 $wrapper.closest('.BoxBottom').addClass('as-container'); 18099 $wrapper.closest('.card').addClass('as-container'); 18100 18101 var input = $(this); 18102 opts.start.call(this); 18103
18104 this.getSelectedValues = getSelectedValues; 18105 this.getSelectedNames = getSelectedNames; 18106 this.getSelected = getSelected; 18107 this.removeAt = removeAt; 18108 this.getValueAt = getValueAt; 18109 this.getNameAt = getNameAt; 18110 this.count = count; 18111 this.selectionLimit = selectionLimit; 18112 this.containsValue = containsValue; 18113 this.addSelection = addSelection; 18114 this.addSelections = addSelections; 18115 this.clearSelections = clearSelections; 18116 this.clearSelection = clearSelections; 18117 this.setEnabled = setEnabled; 18118 this.setExtraParams = setExtraParams; 18119 this.getNewTextAllowed = () => opts.newTextAllowed; 18120 var me = this 18121 18122 this.bound = true; 18123 input.addClass("as-input").attr("id", x_id).val("").attr('placeholder', opts.startText); 18124 var input_focus = false; 18125 18126 // Setup basic elements and render them to the DOM 18127 18128 if (!input.parents('.as-selections').length) { //its possible to have correct DOM without javascript bound to elements 18129 input 18130 .wrap(`<ul style="width:${opts.width};" class="as-selections ${opts.enabled === false ? ' search-disabled' : ''}" id="as-selections-${x}"></ul>`) 18131 .wrap('<li class="as-original" id="as-original-' + x + '"></li>'); 18132 } 18133 18134 var selections_holder = input.parents("#as-selections-" + x); 18135 var org_li = input.parents("#as-original-" + x).last(); 18136 18137 var results_holder = $(`<div class="as-results" id="as-results-${x}"></div>`).hide(); 18138 var results_ul = $(`<ul class="as-list"></ul>`); 18139 var values_input = $(`<input type="hidden" class="as-values" name="as_values_${x_name}" id="as-values-${x}" />`); 18140 var names_input = $(`<input type="hidden" class="as-names" name="as_names_${x_name}" id="as-names-${x}" />`); 18141 let prefill_value = ""; 18142 18143 if (input.attr("prefill")) { 18144 try { 18145 opts.preFill = JSON.parse(input.attr("prefill")); 18146 } 18147 catch (exc) { console.warn(exc); } 18148 } 18149 18150 if (input.attr("minchars") !== undefined) { 18151 opts.minChars = Number(input.attr("minchars")); 18152 } 18153 18154 if (input.attr("enabled") !== undefined) { 18155 opts.enabled = input.attr("enabled") === 'True' || input.attr("enabled") === 'true'; 18156 } 18157 18158 const selAdd = input.attr("selectionAdded"); 18159 if (selAdd) { 18160 try { 18161 opts.selectionAdded = new Function('elem', 'data', selAdd); 18162 } 18163 catch (exc) { console.warn(exc); } 18164 } 18165 18166 const selRem = input.attr("selectionRemoved"); 18167 if (selRem) { 18168 try { 18169 opts.selectionRemoved = new Function('elem', 'data', selRem); 18170 } 18171 catch (exc) { console.warn(exc); } 18172 } 18173 18174 const selChanged = input.attr("selectionChanged"); 18175 if (selChanged) { 18176 try { 18177 opts.selectionChanged = new Function('elem', 'data', selChanged); 18178 } 18179 catch (exc) { console.warn(exc); } 18180 } 18181 18182 const selClick = input.attr("selectionClick"); 18183 if (selClick) { 18184 try { 18185 opts.selectionClick = new Function('elem', 'data', selClick); 18186 } 18187 catch (exc) { console.warn(exc); } 18188 } 18189 18190 const newTextAdded = input.attr("clientNewTextAdded"); 18191 if (newTextAdded) { 18192 try { 18193 opts.clientNewTextAdded = new Function('data', newTextAdded); 18194 } 18195 catch (exc) { console.warn(exc); } 18196 } 18197 18198 var sAdd = opts.selectionAdded; //disable selectionAdded() during prefill 18199 opts.selectionAdded = function () { }; 18200 18201 if (typeof opts.preFill === "string") { 18202 let vals = opts.preFill.split(opts.delimeter); 18203 for (let i = 0; i < vals.length; i++) { 18204 let v_data = {}; 18205 v_data[opts.selectedValuesProp] = vals[i]; 18206 if (vals[i] !== "") { 18207 add_selected_item(v_data, true); 18208 } 18209 } 18210 prefill_value = opts.preFill; 18211 values_input.val(prefill_value); 18212 } 18213 else { 18214 if (opts.preFill && !Array.isArray(opts.preFill)) { 18215 opts.preFill = [opts.preFill]; 18216 } 18217 18218 if (Array.isArray(opts.preFill)) { 18219 opts.preFill 18220 .filter(item => item !== null) 18221 .forEach(item => { 18222 let new_v = item[opts.selectedValuesProp]; 18223 if (new_v == undefined) { new_v = ""; } 18224 prefill_value = new_v; 18225 if (new_v == 0 || new_v != "") { 18226 add_selected_item(item, true); 18227 } 18228 });
18229 } 18230 } 18231 18232 opts.selectionAdded = sAdd; //restore 18233 18234 if (prefill_value != "") { 18235 input.val(""); 18236 $("li.as-selection-item", selections_holder).addClass("blur").removeClass("selected"); 18237 } 18238 input.after(values_input); 18239 values_input.after(names_input); 18240 18241 input.on('focus', onInputFocus); 18242 selections_holder.on('click', function () { 18243 FocusInput(); 18244 lastKeyPressCode = null; 18245 18246 if (opts.minChars === 0) { 18247 keyChange(); 18248 } 18249 }); 18250 18251 results_holder.get(0).containerParent = $wrapper.get(0); 18252 $('body').append(results_holder); 18253 18254 var timeout = null; 18255 var tab_press = false; 18256 18257 var blurFromFocus = function () { 18258 $("li.as-selection-item", selections_holder).addClass("blur").removeClass("selected"); 18259 hideResults(); 18260 input_focus = false; 18261 18262 if (opts.newTextAllowed && input.val() !== "") { 18263 selectCustomText(); 18264 } 18265 else if (!opts.newTextAllowed || input.val() === "") { 18266 input.val(""); 18267 input.attr('placeholder', getSelectedNames().length ? opts.startAgainText : opts.startText); 18268 } 18269 }; 18270 18271 $(window).on("click", function (e) { 18272 if (input_focus && !$(e.target).closest(".as-results").length && !$(e.target).closest(selections_holder).length) { 18273 blurFromFocus(); 18274 } 18275 }); 18276 18277 // mainly for sortable table sidescroll 18278 $('table').on("scroll", function (e) { 18279 if (input_focus && !$(this).closest(".as-results").length && !$(e.target).closest(selections_holder).length) { 18280 blurFromFocus(); 18281 } 18282 }); 18283 18284 const isNewTextCommitKey = (e) => 18285 opts.newTextAllowed 18286 && (e.keyCode === 188 && !opts.allowCommaInNewText || e.keyCode === 13 || e.keyCode === 9); 18287 18288 // Handle input field events 18289 input 18290 .on("focus", function () { 18291 if (values_input.val() === "") { 18292 $(this).val(""); 18293 } else if (input_focus) { 18294 $("li.as-selection-item", selections_holder).removeClass("blur"); 18295 if ($(this).is(':visible') && $(this).val() !== "" && !hasMaxSelections()) { 18296 PositionResultsHolder(results_holder); 18297 } 18298 } 18299 18300 return true; 18301 }) 18302 .on("blur", function () { 18303 var currentVal = $(this).val(); 18304 18305 if (!(currentVal === "" && values_input.val() === "" && prefill_value === "") && input_focus) { 18306 blurFromFocus(); 18307 } 18308 }) 18309 .on("keydown", function (e) { 18310 // track last key pressed 18311 lastKeyPressCode = e.keyCode; 18312 first_focus = false; 18313 if (e.keyCode === 27) {//esc 18314 e.preventDefault(); 18315 input.blur(); 18316 } 18317 else if (e.keyCode === 38) {// up 18318 e.preventDefault(); 18319 moveSelection("up"); 18320 } 18321 else if (e.keyCode === 40) {// down 18322 e.preventDefault(); 18323 moveSelection("down"); 18324 } 18325 else if (e.keyCode === 8) {// delete 18326 if (input.val().length === 1) { 18327 hideResults(); 18328 } 18329 if ($(":visible", results_holder).length > 0) { 18330 if (timeout) { clearTimeout(timeout); } 18331 timeout = setTimeout(function () { keyChange(); }, opts.keyDelay); 18332 } 18333 } 18334 else if (isNewTextCommitKey(e)) { //comma or tab with new text 18335 const active = $("li.active:first", results_holder); 18336 if (active.length > 0) { 18337 active.click(); 18338 if (shouldKeepOpen()) { 18339 e.preventDefault(); 18340 return; 18341 } 18342 hideResults(); 18343 e.preventDefault(); 18344 } 18345 else { 18346 selectCustomText(e); 18347 } 18348 } 18349 else if (!opts.newTextAllowed && (e.keyCode === 188 || e.keyCode === 13 || e.keyCode === 9)) { //enter, or tab without new text 18350 tab_press = false; 18351 const active = $("li.active:first", results_holder); 18352 if (active.length > 0) { 18353 active.click(); 18354 if (shouldKeepOpen()) { 18355 e.preventDefault(); 18356 return; 18357 } 18358 hideResults(); 18359 } 18360 if (opts.neverSubmit) { 18361 e.preventDefault(); 18362 //safari is not selecting new fields properly 18363 var nextIndex = $('input:visible').index(input) + 1; 18364 input.blur(); 18365 $('input:visible').eq(nextIndex).focus(); 18366 } 18367 blurFromFocus(); 18368 } 18369 else { 18370 if (opts.showResultList) { 18371 if (hasMaxSelections()) { 18372 results_ul.html('<li class="as-message">' + opts.limitText + '</li>'); 18373 PositionResultsHolder(results_holder); 18374 } else { 18375 if (timeout) { clearTimeout(timeout); } 18376 timeout = setTimeout(function () { keyChange(); }, opts.keyDelay); 18377 } 18378 } 18379 } 18380 }) 18381 .on("keyup", function (e) { 18382 if (e.keyCode === 38 18383 || e.keyCode === 40 18384 || e.keyCode === 8 18385 || isNewTextCommitKey(e) 18386 || e.keyCode === 13 18387 || e.keyCode === 9 && !opts.newTextAllowed) { 18388 return; 18389 } 18390 18391 if (opts.showResultList) { 18392 if (hasMaxSelections()) { 18393 results_ul.html('<li class="as-message">' + opts.limitText + '</li>'); 18394 PositionResultsHolder(results_holder); 18395 } 18396 else { 18397 if (timeout) { 18398 clearTimeout(timeout); 18399 } 18400 timeout = setTimeout(function () { 18401 keyChange(); 18402 }, opts.keyDelay); 18403 } 18404 } 18405 });
18406 18407 function selectCustomText(e) { 18408 tab_press = true; 18409 const i_input = opts.allowCommaInNewText 18410 ? input.val().replace(/[()]/g, "").replace(/^[,\s]+|[,\s]+$/g, "") 18411 : input.val().replace(/[(,)]/g, ""); 18412 const selectedNames = names_input.val().split(opts.delimeter).filter(i => i !== ''); 18413 const normalize = (text) => opts.matchCase ? text : text.toLowerCase(); 18414 const typedText = normalize(i_input); 18415 const isDuplicate = selectedNames.some(i => normalize(unescape(i)) === typedText); 18416 18417 if (i_input === "") { 18418 if (e) { 18419 e.preventDefault(); 18420 } 18421 //safari is not selecting new fields properly 18422 let nextIndex = $('input:visible').index(input) + 1; 18423 input.blur(); 18424 $('input:visible').eq(nextIndex).focus(); 18425 } 18426 else if (isDuplicate) { 18427 input.val(""); 18428 if (shouldKeepOpen()) { 18429 keyChange(); 18430 } else { 18431 hideResults(); 18432 } 18433 if (e) { 18434 e.preventDefault(); 18435 } 18436 } 18437 else if (i_input.length >= opts.minChars) { 18438 let n_data = {}; 18439 n_data[opts.selectedItemProp] = i_input; 18440 n_data[opts.selectedValuesProp] = 0; 18441 add_selected_item(n_data); 18442 input.val(""); 18443 if (shouldKeepOpen()) { 18444 keyChange(); 18445 } else { 18446 hideResults(); 18447 } 18448 if (e) { 18449 e.preventDefault(); 18450 } 18451 opts.clientNewTextAdded(n_data); 18452 } 18453 } 18454 18455 function hasMaxSelections() { 18456 return opts.selectionLimit >= 0 && count() >= opts.selectionLimit; 18457 } 18458 18459 function shouldKeepOpen() { 18460 return opts.keepOpenUntilMaxSelections && !hasMaxSelections(); 18461 } 18462 18463 function count() { 18464 return getSelected().length; 18465 } 18466 18467 function hideResults(keepResults) { 18468 SetToRegularZIndex(results_holder); 18469 results_holder.hide(); 18470 $("li.active:first", results_holder).removeClass("active"); 18471 if (!keepResults) { 18472 EmptyResults(); 18473 } 18474 return results_holder; 18475 } 18476 18477 function getSearchString() { 18478 return input.val().trim(); 18479 } 18480 18481 function handleLoadStart() { 18482 selections_holder.addClass("loading"); 18483 } 18484 18485 function handleLoadEnd() { 18486 selections_holder.removeClass("loading"); 18487 } 18488 18489 function keyChange() { 18490 if (hasMaxSelections()) { 18491 return; 18492 } 18493 // ignore if the following keys are pressed: [del] [shift] [capslock] 18494 if (lastKeyPressCode === 46 || (lastKeyPressCode > 8 && lastKeyPressCode < 32)) { 18495 return hideResults(); 18496 } 18497 var search = getSearchString(); 18498 if (search.length >= opts.minChars) { 18499 handleLoadStart(); 18500 if (d_type === "string") { 18501 let limit = ""; 18502 if (opts.retrieveLimit) { 18503 limit = encodeURIComponent(opts.retrieveLimit); 18504 } 18505 if (opts.beforeRetrieve) { 18506 search = opts.beforeRetrieve.call(me, search); 18507 } 18508 18509 aborter.abort('New request received'); 18510 aborter = new AbortController(); 18511 18512 let optsExtraParamsResult = opts.GetExtraParams(); 18513 if (optsExtraParamsResult === undefined) { 18514 optsExtraParamsResult = ""; 18515 } 18516 18517 if (req_string) { 18518 const searchParams = new URLSearchParams({}); 18519 18520 if (limit) 18521 searchParams.set("limit", limit); 18522 18523 for (const p of new URLSearchParams(optsExtraParamsResult).entries()) { 18524 searchParams.set(p[0].toLowerCase(), p[1]); 18525 } 18526 18527 for (const p of new URLSearchParams(opts.extraParams).entries()) { 18528 searchParams.set(p[0].toLowerCase(), p[1]); 18529 } 18530 18531 fetch( 18532 req_string + (req_string.indexOf("?") < 0 ? "?" : "") + opts.queryParam + "=" + encodeURIComponent(search) + (searchParams.size > 0 ? '&' + searchParams.toString() : ''), 18533 { 18534 signal: aborter.signal, 18535 headers: { 18536 'Content-Type': 'application/json' 18537 } 18538 }) 18539 .then((res) => { 18540 if (!res.ok) { 18541 d_count = 0; 18542 processData([], search); 18543 return; 18544 } 18545 18546 res.json().then(data => { 18547 d_count = 0; 18548 let new_data = opts.retrieveComplete.call(me, data); 18549 for (k in new_data) { 18550 if (new_data.hasOwnProperty(k)) d_count++; 18551 } 18552 processData(new_data, search); 18553 });
18554 }) 18555 .catch(reason => console.log(`autosuggest: ${reason}`)); 18556 } 18557 } else { 18558 if (opts.beforeRetrieve) { 18559 search = opts.beforeRetrieve.call(me, search); 18560 } 18561 processData(org_data, search, true); 18562 } 18563 } else { 18564 handleLoadEnd(); 18565 hideResults(getSearchString().length === 0); 18566 } 18567 } 18568 18569 function EmptyResults() { 18570 results_holder.html(results_ul.html("")).hide(); 18571 } 18572 18573 var num_count = 0; 18574 function processData(data, query, matchOnClient) { 18575 if (!opts.matchCase) { query = query.toLowerCase(); } 18576 var matchCount = 0; 18577 EmptyResults(); 18578 for (let i = 0; i < d_count; i++) { 18579 let num = i; 18580 num_count++; 18581 let forward = true; 18582 let str = ''; 18583 let styleStr = ''; 18584 18585 if (opts.useCustomStyle && data[num].extraJSON.style) { 18586 styleStr = 'style="' + data[num].extraJSON.style + '"'; 18587 } 18588 18589 if (opts.searchObjProps == "value") { 18590 str = data[num].value; 18591 } else { 18592 let names = opts.searchObjProps.split(opts.delimeter); 18593 for (var y = 0; y < names.length; y++) { 18594 var name = $.trim(names[y]); 18595 str = str + data[num][name] + " "; 18596 } 18597 } 18598 18599 if (str) { 18600 if (!opts.matchCase) { str = str.toLowerCase(); } 18601 18602 const matchesSearchQuery = str.search(query) != -1; 18603 if (!matchesSearchQuery && !!matchOnClient) { 18604 forward = false; 18605 } else if (opts.noDuplicates) { 18606 const selectedValues = values_input.val() ? values_input.val().split(opts.delimeter).filter(v => v !== "") : []; 18607 const rawValue = data[num][opts.selectedValuesProp]; 18608 const currentValue = rawValue === undefined || rawValue === null ? '' : String(rawValue); 18609 const isAlreadySelected = selectedValues.some(v => unescape(v) === currentValue); 18610 forward = !isAlreadySelected; 18611 } 18612 } 18613 18614 if (forward) { 18615 let formatted = $('<li ' + styleStr + ' class= "as-result-item" id = "as-result-item-' + num_count + '" ></li > ') 18616 .on('click', function () { 18617 const raw_data = $(this).data("data"); 18618 if ($("#as-selection-" + raw_data.num_count, selections_holder).length <= 0 && !tab_press) { 18619 const search = getSearchString(); 18620 input.val(""); 18621 add_selected_item(raw_data.attributes); 18622 opts.resultClick.call(me, raw_data); 18623 if (shouldKeepOpen()) { 18624 keyChange(); 18625 } else { 18626 hideResults(search.length === 0); 18627 } 18628 FocusInput(); 18629 } 18630 tab_press = false; 18631 }) 18632 .on('mousedown', function () { 18633 input_focus = false; 18634 }) 18635 .on('mouseover', function () { 18636 $("li", results_ul).removeClass("active"); 18637 $(this).addClass("active"); 18638 }) 18639 .data("data", { attributes: data[num], num: num_count }); 18640 18641 var this_data = $.extend({}, data[num]); 18642 let regx = new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + query.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + ")(?![^<>]*>)(?![^&;]+;)", opts.matchCase ? "g" : "gi"); 18643 18644 if (query && opts.resultsHighlight) { 18645 this_data[opts.selectedItemProp] = (this_data[opts.selectedItemProp] || "").replace(regx, "<em>$1</em>"); 18646 } 18647 if (!opts.formatList) { 18648 formatted = formatted.html(this_data[opts.selectedItemProp]); 18649 } else { 18650 formatted = opts.formatList.call(me, this_data, formatted); 18651 } 18652 results_ul.append(formatted); 18653 delete this_data; 18654 matchCount++; 18655 if (opts.retrieveLimit && opts.retrieveLimit == matchCount) { break; } 18656 } 18657 } 18658 handleLoadEnd(); 18659 if (matchCount <= 0) { 18660 results_ul.html('<li class="as-message">' + opts.emptyText + '</li>'); 18661 } 18662 18663 PositionResultsHolder(results_holder); 18664 opts.resultsOpenEvent(results_holder); 18665 const showAtTop = results_ul.offset().top > $(document).height() - 200 && opts.allowShowAtTop; 18666 18667 results_holder.css({ 18668 "position": showAtTop ? "relative" : "inline" 18669 });
18670 18671 results_ul.css({ 18672 "width": selections_holder.width(), 18673 "maxHeight": Math.max(200, window.innerHeight - results_ul.offset().top - 40), 18674 "bottom": showAtTop ? "35px" : undefined 18675 }); 18676 18677 opts.resultsComplete.call(me); 18678 } 18679 18680 function add_selected_item(data, silent) { 18681 addSelection(data[opts.selectedItemProp], data[opts.selectedValuesProp], data[opts.selectedExtraProp], silent); 18682 } 18683 18684 function addSelections(selections, silent) { 18685 selections.forEach(i => addSelection(i.name, i.value, undefined, silent)); 18686 } 18687 18688 function addSelection(name, value, extra, silent) { 18689 if (!name) { 18690 return; 18691 } 18692 18693 const vals = values_input.val() ? values_input.val().split(opts.delimeter) : []; 18694 const names = names_input.val() ? names_input.val().split(opts.delimeter) : []; 18695 18696 values_input.val(vals.concat(escape(value)).join(opts.delimeter)); 18697 names_input.val(names.concat(escape(name)).join(opts.delimeter)); 18698 extraSelected.push(extra); 18699 18700 const data = { 18701 [opts.selectedItemProp]: name, 18702 [opts.selectedValuesProp]: value, 18703 [opts.selectedExtraProp]: extra !== undefined ? extra : {} 18704 }; 18705 18706 let num = 1; 18707 while ($('#as-selection-' + num).length > 0) { 18708 num++; 18709 } 18710 18711 const item = $('<li class="as-selection-item" id="as-selection-' + num + '"></li>') 18712 .on('click', function () { 18713 opts.selectionClick.call(me, item, data); 18714 selections_holder.children().removeClass("selected"); 18715 $(this).addClass("selected"); 18716 }) 18717 .on('mousedown', function () { 18718 input_focus = false; 18719 }); 18720 18721 const close = $('<i class="far fa-xmark as-close"></i>').on("click", function () { 18722 const index = selections_holder.find('li.as-selection-item').index(item); 18723 removeAt(index); 18724 SetStateOfInput(); 18725 onInputFocus(); 18726 return false; 18727 }); 18728 18729 org_li.before(item.html(name).append(close)); 18730 if (!silent) { 18731 opts.selectionAdded.call(me, org_li.prev(), data); 18732 opts.selectionChanged.call(me, org_li.prev(), data, 'added'); 18733 } 18734 SetStateOfInput(); 18735 if (!silent) { 18736 FocusInput(); 18737 } 18738 } 18739 18740 function removeAt(index, silent) { 18741 const valueToRemove = getValueAt(index); 18742 const nameToRemove = getNameAt(index); 18743 const extra = getExtraAt(index); 18744 18745 let data = { 18746 value: valueToRemove, 18747 name: nameToRemove, 18748 [opts.selectedExtraProp]: extra 18749 }; 18750 18751 const values = getSelectedValues().map(i => escape(i)); 18752 const names = getSelectedNames().map(i => escape(i)); 18753 18754 values.splice(index, 1); 18755 names.splice(index, 1); 18756 18757 values_input.val(values.join(opts.delimeter)); 18758 names_input.val(names.join(opts.delimeter)); 18759 extraSelected.splice(index, 1); 18760 18761 let item = selections_holder.find('li.as-selection-item').eq(index); 18762 18763 if (!silent) { 18764 opts.selectionRemoved.call(me, item, data); 18765 opts.selectionChanged.call(me, item, data, 'removed'); 18766 } 18767 18768 item.remove(); 18769 input_focus = false; 18770 input.blur(); 18771 18772 SetStateOfInput(); 18773 if (!silent) { 18774 FocusInput(); 18775 } 18776 } 18777 18778 function clearSelections(silent) { 18779 while (count() > 0) { 18780 removeAt(0, silent !== false); 18781 } 18782 } 18783 18784 function setEnabled(enabled) { 18785 opts.enabled = enabled; 18786 input.parents('.as-selections').toggleClass('search-disabled', !enabled); 18787 input.prop('disabled', !enabled); 18788 } 18789 18790 function setExtraParams(extraParams) { 18791 opts.extraParams = extraParams; 18792 } 18793 18794 function getValueAt(index) { 18795 return (getSelectedValues()[index]); 18796 } 18797 18798 function getSelectedValues() { 18799 return (jQuery.grep(unescape(values_input.val()).split(opts.delimeter), 18800 function (n, i) { return (n != ""); }) 18801 ); 18802 } 18803 18804 function getSelected() { 18805 const values = getSelectedValues(); 18806 const names = getSelectedNames(); 18807 18808 return values.map((value, i) => ({ 18809 name: names[i], 18810 [opts.selectedExtraProp]: extraSelected[i], 18811 value 18812 })); 18813 } 18814 18815 function containsValue(test) { 18816 var has = getSelectedValues();
18817 for (var i in has) { 18818 if (has[i] == test) { 18819 return (true); 18820 } 18821 } 18822 return (false); 18823 } 18824 18825 function getNameAt(index) { 18826 return (getSelectedNames()[index]); 18827 } 18828 18829 function getSelectedNames() { 18830 return (jQuery.grep(unescape(names_input.val()).split(opts.delimeter), 18831 function (n, i) { return (n != ""); }) 18832 ); 18833 } 18834 18835 function getExtraAt(index) { 18836 return extraSelected[index]; 18837 } 18838 18839 function selectionLimit(max) { 18840 opts.selectionLimit = max; 18841 SetStateOfInput(); 18842 } 18843 18844 function moveSelection(direction) { 18845 if ($(":visible", results_holder).length > 0) { 18846 var lis = $("li", results_holder); 18847 if (direction == "down") { 18848 var start = lis.eq(0); 18849 } else { 18850 var start = lis.filter(":last"); 18851 } 18852 var active = $("li.active:first", results_holder); 18853 if (active.length > 0) { 18854 if (direction == "down") { 18855 start = active.next(); 18856 } else { 18857 start = active.prev(); 18858 } 18859 } 18860 lis.removeClass("active"); 18861 start.addClass("active"); 18862 } 18863 } 18864 18865 function SetStateOfInput() { 18866 input.show().prop('disabled', false).css('color', ''); 18867 18868 if (hasMaxSelections()) { 18869 if (opts.selectionLimit > 0 || count() > opts.selectionLimit) { 18870 input.hide(); 18871 } 18872 else { 18873 input.prop('disabled', true).css('color', '#999'); 18874 } 18875 } 18876 18877 input.val(''); 18878 } 18879 18880 function onInputFocus () { 18881 if (input_focus) 18882 return; 18883 18884 FocusInput(); 18885 }; 18886 18887 function FocusInput() { 18888 if (!hasMaxSelections() && !input.prop('disabled')) { 18889 input_focus = true; 18890 if (!input.is(':focus')) { 18891 input.focus(); 18892 input.select(); 18893 } 18894 } 18895 } 18896 18897 function PositionResultsHolder($element) { 18898 //transform 18899 const cBounds = $element.get(0).containerParent.getBoundingClientRect(); 18900 const windowBounds = document.body.getBoundingClientRect(); 18901 const windowRightX = windowBounds.x + windowBounds.width; 18902 18903 const xTransform = cBounds.x < 0 18904 ? 0 18905 : cBounds.x + cBounds.width > windowRightX 18906 ? windowRightX - cBounds.width 18907 : cBounds.x; 18908 18909 const yTransform = cBounds.y + cBounds.height > window.innerHeight 18910 ? window.innerHeight + window.scrollY - cBounds.height 18911 : cBounds.y + cBounds.height - windowBounds.y; 18912 18913 $element.css({ 18914 'position': 'absolute', 18915 'width': cBounds.width, 18916 'left': `${xTransform}px`, 18917 'top': `${yTransform}px`, 18918 'display': 'block', 18919 }); 18920 } 18921 18922 function SetToRegularZIndex(element) { 18923 element.closest('.validated-input-wrapper').css('z-index', element.closest('.validated-input-wrapper').attr('data-savedZIndex')); 18924 } 18925 18926 }); 18927 } 18928 } 18929} )( jQuery ); 18930 18931 18932; 18933////pf: javascript/d3/line.js 18934 18935const drawD3MultiLine = function () { 18936 let _data = []; 18937 let _dates = []; 18938 let x = null; 18939 let y = null; 18940 let defaultWidth = window.innerWidth; 18941 let defaultHeight = 600; 18942 18943 const margin = { top: 10, right: 20, bottom: 40, left: 25 }; 18944 let width = 0; 18945 let height = 0; 18946 18947 const colors = [ 18948 '#35A8E0', 18949 '#4ECE72', 18950 '#AF5CF7', 18951 '#E05F1D', 18952 '#f94144', 18953 '#577590', 18954 '#f3722c', 18955 '#871b4a', 18956 '#43aa8b', 18957 '#f9c74f', 18958 '#A7A5C6', 18959 '#8797b2', 18960 '#6d8a96', 18961 '#90be6d', 18962 '#66ced6', 18963 '#053c5e', 18964 '#a31621', 18965 '#b5ef8a' 18966 ]; 18967 18968 function hover(svg, path) { 18969 if ("ontouchstart" in document) { 18970 svg 18971 .style("-webkit-tap-highlight-color", "transparent") 18972 .on("touchmove", moved) 18973 .on("touchstart", entered) 18974 .on("touchend", left) 18975 } 18976 else { 18977 svg 18978 .on("mousemove", moved) 18979 .on("mouseenter", entered) 18980 .on("mouseleave", left); 18981 } 18982 18983 const dot = svg.append("g") 18984 .attr("display", "none"); 18985 18986 dot.append("circle") 18987 .attr("r", 4); 18988 18989 18990 const dotLabel = dot.append("g"); 18991 18992 dotLabel.append("rect") 18993 .attr("width", 240) 18994 .attr("height", 40) 18995 .attr("transform", `translate(-2,-14)`) 18996 .style("fill", "rgba(255,255,255,0.95)") 18997 .style("outline", "1px solid #999"); 18998 18999 dotLabel.append("text") 19000 .attr("class", "text1") 19001 .attr("font-family", "sans-serif") 19002 .attr("font-size", 10); 19003 19004 dotLabel.append("text") 19005 .attr("class", "text2") 19006 .attr("font-family", "sans-serif") 19007 .attr("font-size", 10) 19008 .attr("y", 20); 19009 19010 function moved(event) { 19011 event.preventDefault(); 19012 const pointer = d3.pointer(event, this); 19013 const xm = x.invert(pointer[0]); 19014 const ym = y.invert(pointer[1]); 19015 const i = d3.bisectCenter(_dates, xm); 19016 const s = d3.least(_data, d => Math.abs(d.values[i]?.value - ym)); 19017 if (s) { 19018 const date = _dates[i]; 19019 const value = s.values[i].value; 19020 19021 if (value === null) 19022 return; 19023 19024 const formattedValue = s.values[i].formattedValue
19025 || value.toLocaleString('en-US'); 19026 19027 const dateLabel = s.values[i].dateLabel; 19028 19029 const shiftLeft = pointer[0] > width / 2 ? -200 : 0; 19030 const shiftDown = pointer[1] > height / 2 ? -50 : 30; 19031 19032 path.attr("stroke", d => d === s ? null : "#ddd").filter(d => d === s).raise(); 19033 dot.attr("transform", `translate(${x(date)},${y(value)})`); 19034 dot.select(".text1").text(`${formattedValue || value} ${s.name}`); 19035 dot.select(".text2").text(dateLabel || `${moment(date).format("MMMM Do")}`); 19036 dotLabel.attr("transform", `translate(${shiftLeft},${shiftDown})`); 19037 } 19038 } 19039 19040 function entered() { 19041 path.style("mix-blend-mode", null).attr("stroke", "#ddd"); 19042 dot.attr("display", null); 19043 } 19044 19045 function left() { 19046 path.style("mix-blend-mode", "multiply").attr("stroke", null); 19047 dot.attr("display", "none"); 19048 } 19049 } 19050 19051 function redraw({ dates, selector, xDomain, yDomain, chartWidth, chartHeight, yAxisTitle, legendPosition, aggregatedTotals, customTotal }) { 19052 $(selector).html('').addClass('d3 line'); 19053 19054 defaultWidth = $(selector).width(); 19055 width = (chartWidth || defaultWidth); 19056 height = (chartHeight || defaultHeight); 19057 19058 if (legendPosition === 'right') { 19059 width -= 150; 19060 } 19061 19062 const _xDomain = xDomain.map((d) => d3.timeParse("%m/%e/%Y")(d)); 19063 _dates = dates.map(d => d3.timeParse("%m/%e/%Y")(d)); 19064 19065 x = d3.scaleTime() 19066 .range([margin.left, width - margin.right]); 19067 19068 y = d3.scaleLinear() 19069 .range([height - margin.bottom, margin.top]); 19070 19071 const line = d3.line.call(this) 19072 .x((d) => x(d.date)) 19073 .y(d => y(d.value)) 19074 .defined((d) => d.value !== null && d.value !== undefined); 19075 19076 const svg = d3.select(selector).append("svg") 19077 .attr("width", "100%") 19078 .attr("viewBox", `0 0 ${chartWidth || defaultWidth} ${chartHeight || defaultHeight}`); 19079 19080 tooltip = d3.select(selector).append("div") 19081 .attr("class", "tooltip") 19082 .style("display", "none"); 19083 19084 x.domain(_xDomain); 19085 y.domain(yDomain); 19086 19087 const xCall = d3.axisBottom(x) 19088 .ticks(width / 80) 19089 .tickSizeInner(0) 19090 .tickSizeOuter(0) 19091 .tickSize(0) 19092 .tickFormat(d3.timeFormat("%m/%d/%y")) 19093 19094 const xAxis = g => g 19095 .attr("transform", `translate(0,${height - margin.bottom})`) 19096 .call(xCall); 19097 19098 const xAxisGroup = svg.append("g") 19099 .attr("class", "x axis") 19100 .attr("transform", "translate(0," + (height - margin.bottom) + ")") 19101 .call(xAxis); 19102 19103 if (legendPosition === 'right') { 19104 const key = svg.append("g") 19105 .attr("class", "key right"); 19106 19107 let i = 0; 19108 _data.forEach(path => { 19109 key.append("rect") 19110 .style("transform", `translate(0, ${i * 22 - 9}px)`) 19111 .style('fill', colors[i % colors.length]); 19112 19113 key.append("text").text(path.name) 19114 .style("transform", `translate(15px, ${i * 22}px)`); 19115 19116 i++; 19117 }); 19118 } 19119 else { 19120 const key = _data.map((path, i) => { 19121 let total; 19122 if (customTotal) { 19123 total = customTotal 19124 } 19125 else if (path.total) { 19126 total = path.total 19127 } else if (aggregatedTotals) { 19128 total = path.values.reduce((acc, i) => acc + i.value, 0); 19129 } else { 19130 total = path.values[path.values.length - 1].value; 19131 } 19132 19133 return ` 19134 <div class='html-key-child'> 19135 <div>${path.name}</div> 19136 <div class='value' style="color: ${colors[i % colors.length]}">
19136${total?.toLocaleString()}</div> 19137 </div> 19138 `; 19139 }); 19140 19141 $(selector).prepend(`<div class="html-key pb">${key.join('\n')}</div>`); 19142 } 19143 19144 const yCall = d3.axisLeft(y) 19145 .tickSizeInner(0) 19146 .tickSizeOuter(0) 19147 .tickSize(0) 19148 // tickcount needs to be set to 5 to avoid overlapping labels 19149 .ticks(5) 19150 // format tick with "k" for thousands, don't show decimals 19151 .tickFormat(d => d3.format(".0s")(d).replace("G", "B")); 19152 19153 19154 const yAxis = g => g 19155 .attr("transform", `translate(${margin.left},0)`) 19156 .call(yCall) 19157 .call(g => g.select(".domain").remove()) 19158 .call(g => g.select(".tick:last-of-type text").clone() 19159 .attr("x", 3) 19160 .attr("text-anchor", "start") 19161 .attr("font-weight", "bold") 19162 .text(yAxisTitle)); //TODO: check either here or in the next section 19163 19164 svg.append("g") 19165 .attr("class", "y axis") 19166 .call(yAxis) 19167 .append("text") 19168 .attr("transform", "rotate(-90)") 19169 .attr("y", 6) 19170 .attr("dy", ".71em") 19171 .style("text-anchor", "end") 19172 .text(""); 19173 19174 const vx = svg.append("g") 19175 .attr("class", "vx axis") 19176 .append("g") 19177 .attr("class", "tick"); 19178 19179 const xTickPositionsByData = {}; 19180 xAxisGroup.selectAll(".tick").each(function (data) { 19181 if (!xTickPositionsByData[data]) { 19182 const tick = d3.select(this); 19183 const pos = tick.attr("transform").split(/[,()]+/); 19184 xTickPositionsByData[data.toUTCString()] = parseFloat(pos[1]); 19185 } 19186 }); 19187 19188 _data.forEach(series => { 19189 series.values.forEach((value, index) => { 19190 if (value.markDate) { 19191 const dateUtcString = value.date.toUTCString(); 19192 let left = xTickPositionsByData[dateUtcString]; 19193 if (left === undefined) { 19194 left = (width - margin.left - margin.right) * index / dates.length + margin.left; 19195 } 19196 vx.append("line") 19197 .attr("x1", left) 19198 .attr("x2", left) 19199 .attr("y1", margin.top) 19200 .attr("y2", height - margin.bottom) 19201 .style("stroke", "#BBB"); 19202 19203 vx.append("text") 19204 .text(value.markDate) 19205 .style("transform", `translate(${left + 4}px, ${margin.top + 20}px) rotate(90deg)`) 19206 .style("fill", "#999") 19207 .style("font-size", "12px"); 19208 } 19209 }) 19210 }); 19211 19212 let colorIndex = 0; 19213 // const bars = _data.filter(d => d.type === 'bar'); // no bars for now 19214 const bars = []; 19215 const valueOffsets = {}; 19216 19217 if (bars.length > 0) { 19218 const innerHeight = height - margin.bottom; 19219 19220 const barGroup = svg.append("g") 19221 .attr("class", "bar"); 19222 19223 const barWidth = 16; 19224 19225 bars.forEach(series => { 19226 barGroup 19227 .selectAll('.bar') 19228 .data(series.values) 19229 .enter() 19230 .append('rect') 19231 .attr('x', (d) => { 19232 return x(d.date) - barWidth / 2; 19233 }) 19234 .attr('y', (d) => { 19235 const valueOffset = valueOffsets[d.date] || 0; 19236 const yVal = y(d.value + valueOffset); 19237 valueOffsets[d.date] = valueOffset + d.value; 19238 return yVal; 19239 }) 19240 .attr('width', barWidth) 19241 .attr('height', (d) => innerHeight - y(d.value)) 19242 .attr('style', (d) => `fill: ${(d.color || series.color || colors[colorIndex++])};`) 19243 }) 19244 } 19245 19246 const lineGroup = svg.append("g") 19247 .attr("class", "line"); 19248 19249 // const lines = _data.filter(d => d.type === 'line'); // no bars, so all is line 19250 const lines = _data; 19251 19252 if (lines.length > 0) { 19253 const path = lineGroup 19254 .selectAll("path") 19255 .data(lines) 19256 .join("path") 19257 .attr("d", d => line(d.values))
19258 // ! line style - weight might be CSS 19259 .attr("style", d => `stroke: ${colors[colorIndex++ % colors.length]};`) 19260 .attr("stroke-width", 2) 19261 19262 19263 svg.call(hover, path); 19264 } 19265 19266 svg.append("rect") 19267 .attr("class", "overlay") 19268 .attr("width", width) 19269 .attr("height", height); 19270 }; 19271 19272 return ({ data, dates, selector, xDomain, yDomain, chartWidth, chartHeight, yAxisTitle, legendPosition, aggregatedTotals, customTotal }) => { 19273 _data = data; 19274 _data.forEach((series) => { 19275 series.values.forEach(v => { 19276 v.date = d3.timeParse("%m/%e/%Y")(v.date); 19277 }); 19278 }); 19279 19280 let netChartHeight = chartHeight; 19281 19282 if (legendPosition === 'bottom') { 19283 margin.bottom = 20; 19284 if (netChartHeight !== null) 19285 netChartHeight -= 60; 19286 } 19287 19288 redraw({ dates, selector, xDomain, yDomain, chartWidth, chartHeight: netChartHeight, yAxisTitle, legendPosition, aggregatedTotals, customTotal }); 19289 19290 let redrawTimeout = null; 19291 19292 const queueRedraw = () => { 19293 clearTimeout(redrawTimeout); 19294 redrawTimeout = setTimeout( 19295 () => redraw({ dates, selector, xDomain, yDomain, chartWidth, chartHeight: netChartHeight, yAxisTitle, legendPosition }), 19296 250 19297 ); 19298 }; 19299 19300 $('#admin-left-nav [onclick]').on('click', queueRedraw); 19301 $('.horizontal-menu a').on('click', queueRedraw); 19302 $(window).on('resize', queueRedraw); 19303 } 19304}; 19305 19306 19307; 19308////pf: javascript/stats/api/index.js 19309let cachedKApi = null; 19310 19311// eslint-disable-next-line no-redeclare, no-unused-vars 19312function KpiData() { 19313 if (cachedKApi !== null) { 19314 return cachedKApi; 19315 } 19316 19317 async function fetchData(route, params) { 19318 if (!route) { 19319 throw new Error('KpiData: route is required.'); 19320 } 19321 let url = route; 19322 19323 if (params) { 19324 // drop undefined values from params 19325 Object.keys(params).forEach(key => params[key] === undefined && delete params[key]); 19326 const urlParams = new URLSearchParams(params); 19327 url += `?${urlParams}`; 19328 } 19329 19330 const response = await fetch(url); 19331 19332 if (!response.ok) { 19333 throw new Error(`HTTP error! status: ${response.status}`); 19334 } 19335 19336 const data = await response.json(); 19337 19338 return data; 19339 } 19340 19341 const api = { 19342 fetchData 19343 }; 19344 19345 cachedKApi = api; 19346 19347 return api; 19348} 19349 19350; 19351////pf: javascript/stats/api/kpi-client.js 19352/* eslint-disable no-unused-vars */ 19353async function fetchRegistrationsProgressData({ 19354 affiliationIds = getAffiliationIds(), 19355 limits = 4, 19356 timePeriod = KpiTypes.FILTER_TIME_PERIOD.LAST_DAY.value 19357}) { 19358 const route = '/api/dashboard/progress/registrations'; 19359 const params = { affiliationIds, limits, timePeriod }; 19360 return await KpiData().fetchData(route, params); 19361} 19362 19363async function fetchSalesDonutData(params) { 19364 const route = '/api/dashboard/donut/sales'; 19365 return await KpiData().fetchData(route, { ...params, affiliationIds: getAffiliationIds() }); 19366} 19367 19368async function fetchSalesProgressData({ 19369 affiliationIds = getAffiliationIds(), 19370 limit = 4, 19371 timePeriod = KpiTypes.FILTER_TIME_PERIOD.LAST_DAY.value 19372}) { 19373 const route = '/api/dashboard/progress/sales'; 19374 const params = { affiliationIds, limit, timePeriod }; 19375 return await KpiData().fetchData(route, params); 19376} 19377 19378async function fetchRevenueDonutData(params) { 19379 const route = '/api/dashboard/donut/revenue'; 19380 return await KpiData().fetchData(route, { ...params, affiliationIds: getAffiliationIds() }); 19381} 19382 19383async function fetchPaymentsDonutData(params) { 19384 const route = '/api/dashboard/donut/payments'; 19385 return await KpiData().fetchData(route, { ...params, affiliationIds: getAffiliationIds() }); 19386} 19387 19388async function fetchRevenueProgressData(params) { 19389 const route = '/api/dashboard/progress/payments'; 19390 return await KpiData().fetchData(route, { ...params, affiliationIds: getAffiliationIds() }); 19391} 19392 19393async function fetchMarketingEmailsDonutData(params) { 19394 const route = '/api/dashboard/donut/emails'; 19395 return await KpiData().fetchData(route, { ...params, affiliationIds: getAffiliationIds() }); 19396} 19397 19398async function fetchTransactionalEmailsDonutData(params) { 19399 const route = '/api/dashboard/donut/emails'; 19400 return await KpiData().fetchData(route, { ...params, affiliationIds: getAffiliationIds() }); 19401} 19402 19403async function fetchEmailTypeDonutData(params) { 19404 return await KpiData().fetchData('/api/dashboard/donut/communication_type', 19405 { ...params, affiliationIds: getAffiliationIds() } 19406 ); 19407} 19408 19409async function bindEmailsLineGraph(params) { 19410 return await KpiData().fetchData('/api/dashboard/linegraph/emails', 19411 { ...params, affiliationIds: getAffiliationIds() } 19412 ); 19413} 19414 19415async function fetchCollectedFeesDonut(params) { 19416 const route = '/api/dashboard/donut/collected_fees'; 19417 return await KpiData().fetchData(route, { ...params, affiliationIds: getAffiliationIds() }); 19418} 19419 19420/** 19421 * - selector: #StatsDonutTile2__Donut 19422 * - type: donut 19423 * - tile: STATISTICS_TOTAL_RUNNING_EVENTS 19424 */ 19425async function fetchStatsEventsDonut(params) { 19426 const route = '/api/dashboard/donut/statistics_events'; 19427 return await KpiData().fetchData(route, { ...params, affiliationIds: getAffiliationIds() }); 19428} 19429 19430/** 19431 * - selector: #StatsTile3__StackedBarGraph 19432 * - type: Stacked Bar Graph 19433 * - tile: STATISTICS_ATHLETE_REGISTRATIONS 19434 */ 19435async function fetchAthleteRegBarData({ 19436 affiliationIds = getAffiliationIds(), 19437 timePeriod = KpiTypes.FILTER_TIME_PERIOD.CURRENT_FISCAL_YEAR.value 19438}) { 19439 const route = '/api/dashboard/bargraph/registrations_breakdown'; 19440 const params = { 19441 selector: 'NOT_USED', 19442 affiliationIds, 19443 isTeamRegistration: false, 19444 timePeriod 19445 }; 19446 const data = await KpiData().fetchData(route, params); 19447 return data; 19448} 19449 19450async function fetchRegProgressStatData(params) { 19451 const route = '/api/dashboard/progress/registrations_breakdown'; 19452 return await KpiData().fetchData(route, { ...params, affiliationIds: getAffiliationIds() }); 19453} 19454 19455/** 19456 * - selector: #StatsTile6__StackedBarGraph 19457 * - type: Stacked Bar Graph 19458 * - tile: STATISTICS_EXPECTED_PLAYERS_BIG_EVENTS 19459 */ 19460async function fetchBigEventBarData({ affiliationIds = getAffiliationIds(), timePeriod }) { 19461 const params = { affiliationIds, timePeriod }; 19462 return await KpiData().fetchData('/api/dashboard/bargraph/big_events', params); 19463} 19464 19465async function fetchProgramTryoutsData({ selector, affiliationIds }) { 19466 const route = '/api/dashboard/tryouts'; 19467 const params = { selector, affiliationIds }; 19468 const data = await KpiData().fetchData(route, params); 19469 return data; 19470} 19471 19472; 19473////pf: javascript/stats/kpi-utils.js 19474// eslint-disable-next-line no-redeclare 19475const KpiUtils = {}; 19476 19477KpiUtils.isJson = str => { 19478 str = typeof str !== 'string' ? JSON.stringify(str) : str; 19479 try { 19480 str = JSON.parse(str); 19481 } catch (e) { 19482 return false; 19483 } 19484 if (typeof str === 'object' && str !== null) { 19485 return true; 19486 } 19487 return false; 19488}; 19489 19490// This function maps a given percentage value to a corresponding CSS class representing a certain color range. 19491KpiUtils.percentToColorClass = percent => { 19492 if (percent >= 80) return 'percentage-color-80'; 19493 if (percent >= 60) return 'percentage-color-60'; 19494 if (percent >= 40) return 'percentage-color-40'; 19495 if (percent >= 20) return 'percentage-color-20'; 19496 if (percent >= 0) return 'percentage-color-00'; 19497}; 19498 19499KpiUtils.onVisible = (element, callback, notVisibleCallback) => { 19500 try { 19501 new IntersectionObserver((entries, observer) => {
19502 entries.forEach(entry => { 19503 if (entry.intersectionRatio > 0) { 19504 callback(element); 19505 observer.disconnect(); 19506 } 19507 }); 19508 }).observe(element); 19509 } catch (error) { 19510 if (error.name === 'TypeError') { 19511 // throw new TypeError(`KpiUtils.onVisible: {element} is not a valid DOM element. Received ${element || 'null'}.`); 19512 // eslint-disable-next-line no-console 19513 console.warn( 19514 `KpiUtils.onVisible: {element} is not a valid DOM element. Received ${ 19515 element || 'null' 19516 }.` 19517 ); 19518 } 19519 } 19520 19521 // if not visible anymore 19522 if (notVisibleCallback) { 19523 new IntersectionObserver((entries, observer) => { 19524 entries.forEach(entry => { 19525 if (entry.intersectionRatio === 0) { 19526 notVisibleCallback(element); 19527 observer.disconnect(); 19528 } 19529 }); 19530 }).observe(element); 19531 } 19532}; 19533 19534KpiUtils.getElementDimensions = (selector, callback) => { 19535 KpiUtils.onVisible($(selector)[0], () => { 19536 const $el = $(selector); 19537 const siblings = $el.parent().children().length; 19538 19539 $el.css('width', '100%').css('height', '100%'); 19540 19541 const width = $el.width(); 19542 const height = $el.height() / siblings; 19543 19544 callback({ width, height }); 19545 }); 19546}; 19547 19548/** 19549 * @example 19550 * this._debugLayout({ 19551 m: this.margin, 19552 w: this.width, 19553 h: this.height, 19554 _w: this.innerWidth, 19555 _h: this.innerHeight, 19556 sel: this.selector, 19557 svg: this.svg, 19558 }) 19559*/ 19560KpiUtils._debugLayout = ({ m, w, h, _w, _h, sel, svg }) => { 19561 const drawCircle = (x, y, color) => { 19562 const colors = { 19563 red: '#ff0000', 19564 blue: '#0000ff', 19565 green: '#00ff00', 19566 yellow: '#ffff00' 19567 }; 19568 svg.append('circle') 19569 .attr('cx', x) 19570 .attr('cy', y) 19571 .attr('r', 12) 19572 .attr('fill', colors[color] + '88' || color) 19573 .attr('stroke', 'black') 19574 .attr('stroke-width', 1); 19575 }; 19576 const topLeft = drawCircle(0, 0, 'red'); 19577 const topRight = drawCircle(w, 0, 'red'); 19578 const bottomLeft = drawCircle(0, h, 'red'); 19579 const bottomRight = drawCircle(w, h, 'red'); 19580 const innerTopLeft = drawCircle(m.left, m.top, 'blue'); 19581 const innerTopRight = drawCircle(w - m.right, m.top, 'blue'); 19582 const innerBottomLeft = drawCircle(m.left, h - m.bottom, 'blue'); 19583 const innerBottomRight = drawCircle(w - m.right, h - m.bottom, 'blue'); 19584 $(sel).css({ border: '1px solid red' }); 19585 return { 19586 topLeft, 19587 topRight, 19588 bottomLeft, 19589 bottomRight, 19590 innerTopLeft, 19591 innerTopRight, 19592 innerBottomLeft, 19593 innerBottomRight 19594 }; 19595}; 19596 19597KpiUtils.dateToShortMonth = d => new Date(d).toLocaleString('default', { month: 'short' }); 19598 19599KpiUtils.highlightXLabel = function () { 19600 const bbox = this.getBBox(); 19601 d3.select(this.parentNode) 19602 .insert('rect', 'text') 19603 .attr('x', bbox.x - 4) 19604 .attr('y', bbox.y - 3) 19605 .attr('width', bbox.width + 8) 19606 .attr('height', bbox.height + 8) 19607 .attr('fill', '#969696') 19608 .attr('rx', 3) 19609 .attr('ry', 3); 19610}; 19611 19612KpiUtils.shouldHighlightXLabel = timePeriod => { 19613 const periods = KpiTypes.FILTER_TIME_PERIOD; 19614 const ifPeriods = [ 19615 periods.LAST_YEAR.value, 19616 periods.LAST_30_DAYS.value, 19617 periods.NEXT_12_MONTHS.value, 19618 periods.NEXT_FISCAL_YEAR.value, 19619 periods.CURRENT_FISCAL_YEAR.value, 19620 periods.NEXT_12_MONTHS.value, 19621 periods.CALENDAR_YEAR.value 19622 ]; 19623 return ifPeriods.includes(timePeriod); 19624}; 19625 19626KpiUtils.percentGroups = [ 19627 { label: '0-20%', min: 0, color: '#ff6e00' }, 19628 { label: '20-40%', min: 20, color: '#f5aa00' }, 19629 { label: '40-60%', min: 40, color: '#fce400' }, 19630 { label: '60-80%', min: 60, color: '#aadc00' }, 19631 { label: '80-100%', min: 80, color: '#56bf00' } 19632]; 19633 19634KpiUtils.getPercentColor = percent => { 19635 if (percent >= 100) return KpiUtils.colors.keyGreen; 19636 const percentGroup = KpiUtils.getPercentGroup(percent); 19637 const group = KpiUtils.percentGroups.find(g => g.min === percentGroup); 19638 if (group) return group.color; 19639 return KpiUtils.colors.secondary; 19640}; 19641 19642KpiUtils.getPercentGroup = percent => Math.floor(Math.min(percent, 100) / 20) * 20; 19643 19644// converts date of type 1/1/2019 to January 2019 19645KpiUtils.dateToMonthYear = date => { 19646 const d = new Date(date);
19647 const month = d.toLocaleString('default', { month: 'long' }); 19648 const year = d.getFullYear(); 19649 return `${month} ${year}`; 19650}; 19651 19652// format date object to Jan 1, 2019 19653KpiUtils.dateToShortMonthDayYear = date => { 19654 const d = new Date(date); 19655 const month = d.toLocaleString('default', { month: 'short' }); 19656 const day = d.getDate(); 19657 const year = d.getFullYear(); 19658 return `${month} ${day}, ${year}`; 19659}; 19660 19661KpiUtils.getHeaderTimeString = () => { 19662 let d = new Date(); 19663 let time = d 19664 .toLocaleTimeString('en-US', { 19665 hour12: true, 19666 hour: 'numeric', 19667 minute: 'numeric' 19668 }) 19669 .replace(/ /g, ''); 19670 let timezone = d 19671 .toLocaleTimeString('en-US', { timeZoneName: 'short' }) 19672 .split(' ')[2] 19673 .replace(/:/g, ''); 19674 return time + ' ' + timezone; 19675}; 19676 19677KpiUtils.spinner = function (selector, options) { 19678 const $el = $(selector); 19679 const appendToSelf = options && options.appendToSelf; 19680 19681 let spinnerId = 'kpi-spinner-' + Math.floor(Math.random() * 1000000); 19682 const _appendee = appendToSelf ? $el : $el.parent(); 19683 return { 19684 start: () => { 19685 _appendee 19686 .css('position', 'relative') 19687 .append(`<div id=${spinnerId} class="kpi-spinner"><div class="spin"></div></div>`); 19688 }, 19689 end: () => { 19690 $(`#${spinnerId}`).fadeOut(500, () => { 19691 $(`#${spinnerId}`).remove(); 19692 }); 19693 }, 19694 clearTile: () => { 19695 _appendee.find('.kpi-spinner').fadeOut(500, () => { 19696 _appendee.find('.kpi-spinner').remove(); 19697 }); 19698 } 19699 }; 19700}; 19701 19702KpiUtils._tileElementAlert = function (selector, selectSelf = false) { 19703 const $element = !selectSelf ? $(selector).parent() : $(selector); 19704 const $ancestorTile = selectSelf ? $(selector) : $element.closest('.kpi-tile'); 19705 const $tileBody = $ancestorTile.find('.kpi-tile-body'); 19706 19707 return { 19708 show: (title, message) => { 19709 let _message, _title; 19710 _title = title || 'No results available yet'; 19711 _message = message || 'Check back later...'; 19712 19713 const $alert = $(` 19714 <div class="kpi-chart-error tileApiError"> 19715 <div class="container"> 19716 <div class="content"> 19717 <h3>${_title}</h3> 19718 <h6>${_message}</h6> 19719 </div> 19720 </div> 19721 </div> 19722 `); 19723 const $existingAlert = $tileBody.find('.kpi-chart-error'); 19724 19725 const hidePercentageLegend = () => 19726 $ancestorTile.find('.percentage-legend').css('display', 'none'); 19727 const appendAlert = $container => { 19728 return $container.css({ position: 'relative', height: '100%' }).append($alert); 19729 }; 19730 19731 // Assumes that max number of potential alerts is 2 19732 if ($existingAlert.length > 0) { 19733 $existingAlert.remove(); 19734 // append alert to tile body if it is the only alert 19735 appendAlert($tileBody); 19736 hidePercentageLegend(); 19737 return; 19738 } else { 19739 if ($tileBody.children().length === 1) { 19740 hidePercentageLegend(); 19741 } 19742 appendAlert($element); 19743 } 19744 }, 19745 remove: () => { 19746 $ancestorTile.find('.tileApiError, .kpi-tile-body .tileApiError').remove(); 19747 $ancestorTile.find('.percentage-legend').css({ display: 'flex' }); 19748 } 19749 }; 19750}; 19751 19752/** 19753 * SVG utility - place/remove circle on svg 19754 */ 19755KpiUtils.placeSvgCircle = { 19756 /** 19757 * @param {*} svg - d3 svg selection 19758 * @param {*} x - x coordinate 19759 * @param {*} y - y coordinate 19760 * @param {*} color - color of circle, default red for debug 19761 * @param {*} r - radius of circle, default 5 19762 */ 19763 on: (svg, x, y, color = 'red', r = 5) => { 19764 svg.append('circle') 19765 .attr('class', 'util-circle') 19766 .attr('r', r) 19767 .attr('cx', x) 19768 .attr('cy', y) 19769 .attr('fill', color); 19770 }, 19771 /** 19772 * Remove all circles from svg 19773 * @param {*} svg - d3 svg selection 19774 */ 19775 off: svg => { 19776 svg.selectAll('.util-circle').remove(); 19777 } 19778}; 19779 19780KpiUtils.graphTickFormatKM = d => { 19781 d = Math.abs(d); 19782 const format = d3.format('.2s'); 19783 const intFormat = d3.format('d'); 19784 let label = ''; 19785 19786 if (d >= 1e6) { 19787 // 1M or greater 19788 label = format(d / 1e6) + 'M'; 19789 } else if (d >= 5e5) { 19790 // 500K - 999K 19791 label = (d / 1e6).toFixed(1) + 'M'; // 0.5M 19792 } else if (Number.isInteger(d)) { 19793 label = format(d); // 100K - 499K 19794 } 19795 else { 19796 label = ''; 19797 } 19798 return label.replace('.0', ''); 19799};
19800 19801KpiUtils.colors = { 19802 primary: '#25AAE1', 19803 secondary: '#BDBDBD', 19804 positive: '#56BF00', 19805 negative: '#DD0000', 19806 light: '#E2E2E2', 19807 lighter: '#F2F2F2', 19808 dark: '#494949', 19809 darkLabel: '#969696', 19810 gridLine: '#DDDDDD', 19811 /* percent key colors... */ 19812 keyRedOrange: '#ff6e00', 19813 keyOrange: '#f5aa00', 19814 keyYellow: '#fce400', 19815 keyLightGreen: '#aadc00', 19816 keyGreen: '#56bf00' 19817}; 19818 19819// prettier-ignore 19820KpiUtils.colors.danger = [ 19821 '#DD0000', 19822 '#C70B0B', 19823 '#B11616', 19824 '#9A2121', 19825 '#842C2C', 19826 '#6E3737', 19827 '#583F3F', 19828 '#424A4A', 19829]; 19830 19831KpiUtils.removeColumnClasses = element => { 19832 const $element = $(element); 19833 const classes = $element.attr('class').split(' '); 19834 const colClass = classes.filter(c => c.includes('cols-')); 19835 $element.removeClass(colClass); 19836 return $element; 19837}; 19838 19839KpiUtils.findVisibleTiles = container => { 19840 const $container = $(container); 19841 return $container.find('.kpi-tile:visible'); 19842}; 19843 19844KpiUtils.widenSplitTile = tile => { 19845 const $tile = $(tile); 19846 19847 if ($tile.hasClass('rows-2')) { 19848 return; 19849 } 19850 19851 const $body = $tile.find('.kpi-tile-body'); 19852 if ($body.children().length < 2 || $body.hasClass('split-wide')) { 19853 return; 19854 } 19855 19856 $body.children().each(function () { 19857 const $section = $(this); 19858 if (!$section.hasClass('split-wide__section')) { 19859 $section.wrap('<div class="split-wide__section"></div>'); 19860 } 19861 }); 19862 if ($body.find('.split-wide__section').length === 2) { 19863 $body.addClass('split-wide'); 19864 $tile.css('min-height', '524px'); // spec for 2x2 tiles on spotlight page, need to make this a class 19865 } 19866}; 19867 19868KpiUtils.unsplitTile = tile => { 19869 const $tile = $(tile); 19870 if ($tile.hasClass('rows-2')) { 19871 return; 19872 } 19873 19874 const $body = $tile.find('.kpi-tile-body'); 19875 if ($body.hasClass('split-wide')) { 19876 $body.removeClass('split-wide'); 19877 } 19878}; 19879 19880KpiUtils.showPanelOverlay = (panel, show) => { 19881 if ($('#panel-overlay').length) return; 19882 19883 const $panel = panel ? $(panel) : $('#kpi-spotlight-page').parent(); 19884 19885 const $overlay = $('<div id="panel-overlay"></div>').css({ 19886 position: 'absolute', 19887 top: 0, 19888 left: 0, 19889 width: '100%', 19890 height: '100%', 19891 background: '#e2e2e2', 19892 zIndex: 9999 19893 }); 19894 19895 if (show) { 19896 $panel.css('position', 'relative').append($overlay); 19897 $panel.find('.kpi-tile').css('box-shadow', 'none'); 19898 } else { 19899 $('#snapshot-overlay').remove(); 19900 $panel.find('.kpi-tile').css('box-shadow', ''); 19901 $panel.css('position', ''); 19902 } 19903}; 19904 19905KpiUtils.adjustLayoutForFewVisibleTiles = (section, maxNumberTiles) => { 19906 const $tiles = KpiUtils.findVisibleTiles(section); 19907 if ($tiles.length <= maxNumberTiles) { 19908 $tiles.each(function () { 19909 KpiUtils.removeColumnClasses(this); 19910 $(this).addClass('cols-6'); 19911 KpiUtils.unsplitTile(this); 19912 }); 19913 } 19914}; 19915 19916KpiUtils.rerenderTileElement = async ({ 19917 selector, 19918 handleRequest, 19919 handleResponse, 19920 queryParams, 19921 spinner = null, // optional 19922 alert = null, // optional 19923 throwError = false, 19924 spinnerOn = true, 19925 alertOn = true, 19926 useOverridenRender = null 19927}) => { 19928 if (useOverridenRender) { 19929 return useOverridenRender(); 19930 } 19931 // if required params are not provided, throw error 19932 if (!selector || !handleRequest || !handleResponse) { 19933 throw new Error('Missing required params'); 19934 } 19935 19936 const _alert = alert ?? KpiUtils._tileElementAlert(selector); 19937 const _spinner = spinner ?? KpiUtils.spinner(selector); 19938 19939 _alert.remove(); 19940 spinnerOn && _spinner.start(); 19941 19942 try { 19943 const response = await handleRequest(queryParams); 19944 19945 if (response.fail) { 19946 // eslint-disable-next-line no-console 19947 console.warn(response); 19948 alertOn && _alert.show(); 19949 } 19950 19951 handleResponse(response, selector, queryParams); 19952 } catch (error) { 19953 // eslint-disable-next-line no-console 19954 console.error(error); 19955 alertOn && _alert.show(); 19956 if (throwError) throw error; 19957 } finally { 19958 spinnerOn && _spinner.end(); 19959 } 19960}; 19961 19962KpiUtils.rerenderTileAllElements = async tile => { 19963 const promises = tile.elements.map(async element => { 19964 const { 19965 getElementTypeAlertContainer, 19966 _tileElementAlert, 19967 spinner, 19968 isStatsElement, 19969 rerenderTileElement 19970 } = KpiUtils; 19971 const { handleRequest, handleResponse, queryParams, selector, type }
19971 = element; 19972 19973 const alertContainer = getElementTypeAlertContainer(type, selector); 19974 const alert = _tileElementAlert(alertContainer); 19975 const _spinner = spinner(alertContainer, { 19976 appendToSelf: isStatsElement(type) 19977 }); 19978 19979 return await rerenderTileElement({ 19980 selector, 19981 handleRequest, 19982 handleResponse, 19983 queryParams, 19984 spinner: _spinner, 19985 alert 19986 }); 19987 }); 19988 19989 await Promise.all(promises); 19990}; 19991 19992KpiUtils.getTimePeriodTickFormat = timePeriod => { 19993 try { 19994 const periods = KpiTypes.FILTER_TIME_PERIOD; 19995 19996 let format; 19997 switch (timePeriod) { 19998 case periods.LIFETIME.value: 19999 format = d3.timeFormat('%Y'); 20000 break; 20001 case periods.LAST_30_DAYS.value: 20002 case periods.LAST_7_DAYS.value: 20003 // return short month name and day of month 20004 format = d3.timeFormat('%b %-d'); 20005 break; 20006 case periods.LAST_24_HOURS.value: 20007 case periods.YESTERDAY.value: 20008 case periods.TODAY.value: 20009 // return short month name, day of month (no trailing 0's), and time 20010 format = d3.timeFormat('%b %-d %I:%M%p'); 20011 break; 20012 case periods.CURRENT_FISCAL_YEAR.value: 20013 case periods.NEXT_FISCAL_YEAR.value: 20014 case periods.LAST_YEAR.value: 20015 case periods.NEXT_12_MONTHS.value: 20016 default: 20017 // return short month name 20018 format = d3.timeFormat('%b'); 20019 break; 20020 } 20021 return format; 20022 } catch (error) { 20023 // eslint-disable-next-line no-console 20024 console.error( 20025 `Could not get time period tick format for time period => ${timePeriod}`, 20026 error 20027 ); 20028 return d3.timeFormat('%-d %b %y'); 20029 } 20030}; 20031 20032KpiUtils.calculateDateDifference = (date1, date2) => { 20033 if (date2 < date1) { 20034 [date1, date2] = [date2, date1]; 20035 } 20036 const yearsDifference = date2.getFullYear() - date1.getFullYear(); 20037 let monthsDifference = yearsDifference * 12 + date2.getMonth() - date1.getMonth(); 20038 20039 if (date2.getDate() < date1.getDate()) { 20040 monthsDifference--; 20041 } 20042 return { 20043 years: yearsDifference, 20044 totalMonths: monthsDifference 20045 }; 20046}; 20047 20048KpiUtils.getTimePeriodMaxTicksFormat = (timePeriod, domain) => { 20049 const periods = KpiTypes.FILTER_TIME_PERIOD; 20050 20051 const startDate = new Date(domain[0]); 20052 const endDate = new Date(domain[domain.length - 1]); 20053 20054 const timeDiffs = KpiUtils.calculateDateDifference(startDate, endDate); 20055 const yearsBetween = timeDiffs.years; 20056 const monthsBetween = timeDiffs.totalMonths; 20057 20058 let maxTicks; 20059 switch (timePeriod) { 20060 case periods.LIFETIME.value: 20061 maxTicks = yearsBetween; 20062 if (yearsBetween < 1) { 20063 maxTicks = monthsBetween; 20064 } 20065 break; 20066 case periods.CURRENT_FISCAL_YEAR.value: 20067 case periods.NEXT_FISCAL_YEAR.value: 20068 case periods.LAST_YEAR.value: 20069 maxTicks = 12; 20070 break; 20071 case periods.LAST_30_DAYS.value: 20072 maxTicks = 30; 20073 break; 20074 case periods.LAST_7_DAYS.value: 20075 maxTicks = 7; 20076 break; 20077 case periods.LAST_24_HOURS.value: 20078 maxTicks = 24; 20079 break; 20080 case periods.YESTERDAY.value: 20081 case periods.TODAY.value: 20082 maxTicks = 4; 20083 break; 20084 default: 20085 maxTicks = 12; 20086 break; 20087 } 20088 return maxTicks; 20089}; 20090 20091/** 20092 * Calculates the number of ticks to show on the x-axis of a chart 20093 * @param {*} innerWidth - width of the chart 20094 * @param {*} dataLength - number of data points 20095 * @param {*} labelWidth - width of a label 20096 * @returns {number} - number of ticks to show 20097 */ 20098KpiUtils.getResponsiveNumTicks = (innerWidth, dataLength, labelWidth = 84) => { 20099 let ticks = Math.max(5, Math.floor(innerWidth / labelWidth)); 20100 // `ticks` is no bigger than the number of data points in data[0].values 20101 ticks = Math.min(ticks, dataLength); 20102 return ticks; 20103}; 20104 20105KpiUtils.isStatsElement = type => { 20106 const te = KpiTypes.TILE_ELEMENT; 20107 return [te.PROGRESS_STATS, te.SORTABLE_STATS].includes(type); 20108}; 20109 20110KpiUtils.getElementTypeAlertContainer = (type, selector) => { 20111 return KpiUtils.isStatsElement(type) ? $(selector).find('.kpi-progress-list') : selector; 20112}; 20113 20114// Error types
20115class AllValuesZeroException extends Error { 20116 constructor(message) { 20117 super(message); 20118 this.name = 'AllValuesZeroException'; 20119 } 20120} 20121 20122class MissingDataException extends Error { 20123 constructor(message) { 20124 super(message); 20125 this.name = 'MissingDataException'; 20126 } 20127} 20128 20129KpiUtils.renderError = ({ title, message }) => { 20130 const $markup = $(` 20131 <div class="util-error"> 20132 <h3>${title}</h3> 20133 <h6>${message}</h6> 20134 </div> 20135 `); 20136 20137 return $markup; 20138}; 20139 20140 20141; 20142////pf: javascript/stats/types/index.js 20143// eslint-disable-next-line no-redeclare 20144const KpiTypes = {}; 20145 20146KpiTypes.TILE_ELEMENT = { 20147 ECON_UNIT: 'econ_unit', 20148 STACKED_BARS: 'stacked_bar', 20149 WATERFALL: 'waterfall', 20150 MULTILINE: 'multiline', 20151 REV_VS_EXPENSE: 'rev_vs_expense', 20152 TABLE: 'table', 20153 AR_TABLE: 'ar_table', 20154 DONUT: 'donut', 20155 PROGRESS_STATS: 'progress_stats', 20156 SORTABLE_STATS: 'sortable_stats' 20157}; 20158 20159KpiTypes.FILTER_TIME_PERIOD = { 20160 LIFETIME: { 20161 label: 'Lifetime', 20162 value: '0' 20163 }, 20164 CURRENT_FISCAL_YEAR: { 20165 label: `Fiscal ${new Date().getFullYear()}`, 20166 value: '1' 20167 }, 20168 LAST_YEAR: { 20169 label: 'Last 1 Year', 20170 value: '2' 20171 }, 20172 LAST_30_DAYS: { 20173 label: 'Last 30 Days', 20174 value: '3' 20175 }, 20176 LAST_DAY: { 20177 label: 'Last Day', 20178 value: '4' 20179 }, 20180 LAST_24_HOURS: { 20181 label: 'Last 24 Hours', 20182 value: '5' 20183 }, 20184 NEXT_WEEK: { 20185 label: 'Next Week', 20186 value: '6' 20187 }, 20188 NEXT_30_DAYS: { 20189 label: 'Next 30 Days', 20190 value: '7' 20191 }, 20192 NEXT_12_MONTHS: { 20193 label: 'Next 12 Months', 20194 value: '8' 20195 }, 20196 NEXT_FISCAL_YEAR: { 20197 label: `Fiscal ${new Date().getFullYear() + 1}`, 20198 value: '9' 20199 }, 20200 YESTERDAY: { 20201 label: 'Yesterday', 20202 value: '10' 20203 }, 20204 TODAY: { 20205 label: 'Today', 20206 value: '11' 20207 }, 20208 LAST_7_DAYS: { 20209 label: 'Last 7 Days', 20210 value: '12' 20211 }, 20212 CALENDAR_YEAR: { 20213 label: 'Calendar Year', 20214 value: '13' 20215 } 20216}; 20217 20218KpiTypes.FILTER_PROGRAM_TYPE = { 20219 ALL_PROGRAM_TYPES: { 20220 key: 'programTypes', 20221 label: 'All Program Types', 20222 value: 'All' 20223 }, 20224 XPR: { 20225 key: 'programTypes', 20226 label: 'XPR', 20227 value: 'XPR' 20228 }, 20229 EVT: { 20230 key: 'programTypes', 20231 label: 'EVT', 20232 value: 'EVT' 20233 }, 20234 LGE: { 20235 key: 'programTypes', 20236 label: 'LGE', 20237 value: 'LGE' 20238 }, 20239 TMS: { 20240 key: 'programTypes', 20241 label: 'TMS', 20242 value: 'TMS' 20243 } 20244}; 20245 20246KpiTypes.FILTER_BUDGET = { 20247 PER_2: { 20248 label: '2%', 20249 value: '2' 20250 }, 20251 PER_10: { 20252 label: '10%', 20253 value: '10' 20254 }, 20255 PER_25: { 20256 label: '25%', 20257 value: '25' 20258 }, 20259 PER_50: { 20260 label: '50%', 20261 value: '50' 20262 }, 20263 PER_75: { 20264 label: '75%', 20265 value: '75' 20266 }, 20267 PER_100: { 20268 label: '100%', 20269 value: '100' 20270 } 20271}; 20272 20273KpiTypes.FILTER_TYPE = { 20274 PROGRAM_TYPE: { 20275 key: 'programTypes', 20276 label: 'Program Type' 20277 }, 20278 TIME_PERIOD: { 20279 key: 'timePeriod', 20280 label: 'Time Period' 20281 }, 20282 FROM_BUDGET: { 20283 key: 'fromBudget', 20284 label: 'From Budget' 20285 }, 20286 ORDER_BY: { 20287 key: 'orderLowToHigh', 20288 label: 'Order From' 20289 }, 20290 SORT_BY: { 20291 key: 'sortBy', 20292 label: 'Sort By' 20293 }, 20294 PROGRAM_ACTIVE: { 20295 key: 'showActive', 20296 label: 'Filter Programs' 20297 } 20298}; 20299 20300KpiTypes.FILTER_ORDER_BY = { 20301 LOW_TO_HIGH: { 20302 value: 'true', 20303 label: 'Low to High' 20304 }, 20305 HIGH_TO_LOW: { 20306 value: 'false', 20307 label: 'High to Low' 20308 } 20309}; 20310 20311KpiTypes.FILTER_SORT_BY = { 20312 SORT_BY_PROFIT: { 20313 value: 'Profit', 20314 label: 'Profit Margin' 20315 }, 20316 SORT_BY_REVENUE: { 20317 value: 'Revenue', 20318 label: 'Revenue' 20319 }, 20320 SORT_BY_EXPENSE: { 20321 value: 'Expenses', 20322 label: 'Expenses' 20323 } 20324}; 20325KpiTypes.FILTER_PROGRAM_ACTIVE = { 20326 SHOW_ALL: { 20327 value: 'false', 20328 label: 'All Programs' 20329 }, 20330 SHOW_ONLY_ACTIVE: { 20331 value: 'true', 20332 label: 'Currently Active Programs' 20333 } 20334}; 20335 20336// orignal spec starts at lifetime to last 30 days 20337KpiTypes.time_periods_lifetime_to_last30 = [ 20338 KpiTypes.FILTER_TIME_PERIOD.LIFETIME, 20339 KpiTypes.FILTER_TIME_PERIOD.CURRENT_FISCAL_YEAR, 20340 KpiTypes.FILTER_TIME_PERIOD.CALENDAR_YEAR, 20341 KpiTypes.FILTER_TIME_PERIOD.LAST_YEAR, 20342 KpiTypes.FILTER_TIME_PERIOD.LAST_30_DAYS, 20343 KpiTypes.FILTER_TIME_PERIOD.LAST_7_DAYS, 20344 KpiTypes.FILTER_TIME_PERIOD.LAST_24_HOURS, 20345 KpiTypes.FILTER_TIME_PERIOD.YESTERDAY, 20346 KpiTypes.FILTER_TIME_PERIOD.TODAY 20347]; 20348 20349// orignal spec starts at last 30 days to last 7 days
20350KpiTypes.time_periods_last30_to_last7 = [ 20351 KpiTypes.FILTER_TIME_PERIOD.LAST_30_DAYS, 20352 KpiTypes.FILTER_TIME_PERIOD.LAST_7_DAYS, 20353 KpiTypes.FILTER_TIME_PERIOD.LAST_24_HOURS, 20354 KpiTypes.FILTER_TIME_PERIOD.YESTERDAY, 20355 KpiTypes.FILTER_TIME_PERIOD.TODAY 20356]; 20357 20358// orignal spec starts at next fiscal year to next 30 days 20359KpiTypes.time_periods_current_fiscal_to_next30 = [ 20360 KpiTypes.FILTER_TIME_PERIOD.CURRENT_FISCAL_YEAR, 20361 KpiTypes.FILTER_TIME_PERIOD.NEXT_12_MONTHS, 20362 KpiTypes.FILTER_TIME_PERIOD.NEXT_FISCAL_YEAR, 20363 KpiTypes.FILTER_TIME_PERIOD.CALENDAR_YEAR, 20364 KpiTypes.FILTER_TIME_PERIOD.NEXT_30_DAYS 20365]; 20366 20367KpiTypes.budgets_all = [ 20368 KpiTypes.FILTER_BUDGET.PER_2, 20369 KpiTypes.FILTER_BUDGET.PER_10, 20370 KpiTypes.FILTER_BUDGET.PER_25, 20371 KpiTypes.FILTER_BUDGET.PER_50, 20372 KpiTypes.FILTER_BUDGET.PER_75, 20373 KpiTypes.FILTER_BUDGET.PER_100 20374]; 20375 20376KpiTypes.program_types_all = [ 20377 KpiTypes.FILTER_PROGRAM_TYPE.ALL_PROGRAM_TYPES, 20378 KpiTypes.FILTER_PROGRAM_TYPE.XPR, 20379 KpiTypes.FILTER_PROGRAM_TYPE.EVT, 20380 KpiTypes.FILTER_PROGRAM_TYPE.LGE, 20381 KpiTypes.FILTER_PROGRAM_TYPE.TMS 20382]; 20383 20384KpiTypes.program_activity = [ 20385 KpiTypes.FILTER_PROGRAM_ACTIVE.FILTER_SHOW_ALL, 20386 KpiTypes.FILTER_PROGRAM_ACTIVE.FILTER_SHOW_ONLY_ACTIVE 20387]; 20388 20389 20390; 20391////pf: javascript/stats/kpi-tile-2.js 20392function DashboardTile({ 20393 parent, 20394 index, 20395 tooltip, 20396 title, 20397 classNames, 20398 indicators = [], 20399 showPercentKey 20400}) { 20401 const $template = ` 20402 <div class="kpi-tile"> 20403 <header> 20404 <div class="header-group"> 20405 <a href="#" data-tooltip></a> 20406 <h2 class="title"></h2> 20407 <div data-controls></div> 20408 </div> 20409 <ul data-indicators></ul> 20410 </header> 20411 <div class="kpi-tile-body"></div> 20412 </div> 20413 `; 20414 20415 let $element = null; 20416 20417 const init = () => { 20418 $element = $($template).attr('data-tile-id', index).addClass(classNames); 20419 if (tooltip) setTooltip(tooltip); 20420 $element.find('.title').text(title); 20421 setIndicators(indicators); 20422 20423 if (showPercentKey) { 20424 $element.append(PercentKey.html); 20425 } 20426 }; 20427 20428 const setTooltip = (text = tooltip) => { 20429 const $tooltip = $element.find('[data-tooltip]'); 20430 20431 // if tooltip has an icon already, skip, else add it 20432 if (!$tooltip.find('i').length) { 20433 $tooltip.prepend("<i class='fas fa-circle-question'></i>"); 20434 } 20435 20436 $tooltip 20437 .hover( 20438 function () { 20439 $('<p class="kpi-tile-tooltip"></p>').text(text).appendTo('body').show(); 20440 }, 20441 function () { 20442 $('.kpi-tile-tooltip').remove(); 20443 } 20444 ) 20445 .mousemove(function (e) { 20446 const left = e.pageX + 20; 20447 const top = e.pageY + 10; 20448 $('.kpi-tile-tooltip').css({ top, left }); 20449 }); 20450 $tooltip.click(function (e) { 20451 e.preventDefault(); 20452 }); 20453 }; 20454 20455 const setIndicators = indicators => { 20456 const $indicators = $element.find('[data-indicators]'); 20457 $indicators.empty(); 20458 indicators.forEach(indicator => { 20459 const $indicator = $('<li>').text(indicator); 20460 $indicators.append($indicator); 20461 }); 20462 }; 20463 20464 const render = (selector = parent) => { 20465 $(selector).append($element); 20466 }; 20467 20468 const destroy = () => { 20469 $element.remove(); 20470 }; 20471 20472 // Initialize the instance 20473 init(); 20474 20475 // Return an object that represents the public API 20476 return { 20477 render, 20478 destroy, 20479 $element, 20480 body: $element.find('.kpi-tile-body') 20481 }; 20482} 20483 20484 20485; 20486////pf: javascript/stats/kpi-tile.js 20487// eslint-disable-next-line no-redeclare 20488class KpiTile { 20489 constructor({ 20490 selector, 20491 controls, 20492 indicatorList, 20493 title, 20494 tooltip, 20495 columns, 20496 rows, 20497 tileId, 20498 callback, 20499 className 20500 }) { 20501 // try { 20502 this.selector = selector; 20503 this.className = className; 20504 20505 if (controls && controls.length) 20506 controls.forEach(control => { 20507 if (!this.CONTROLS_LIST.includes(control)) { 20508 console.warn( 20509 `KpiTile: ${control} is not a valid control. Valid controls are: ${this.CONTROLS_LIST.join( 20510 ', ' 20511 )}.` 20512 ); 20513 } else { 20514 this.controls.push(control); 20515 } 20516 }); 20517 this.indicatorList = indicatorList; 20518 20519 this.title = title || ''; 20520 if (!this.title) { 20521 console.warn( 20522 'KpiTile: title is required. If you do not want a title, provide an empty string.' 20523 ); 20524 // TODO: uncomment this line when we are ready to throw errors 20525 // throw new Error(`KpiTile: title is required. If you do not want a title, provide an empty string.`) 20526 } 20527 this.tooltip = tooltip; 20528 this.columns = columns || 4; 20529 this.rows = rows; 20530 this.tileId = tileId; 20531 this.callback = callback; 20532 20533 this.init(); 20534 // } catch (error) { 20535 // console.error(`KpiTile: ${error.message}.`) 20536 // } 20537 } 20538 20539 CONTROLS_LIST = ['expand', 'external-link', 'options']; 20540 controls = []; 20541 indicatorList = []; 20542 $element = null; 20543 20544 init() { 20545 this.createTile(); 20546 KpiTile.initTileMarkup(this.$element); 20547 } 20548 20549 get body() { 20550 return this.$element.find('.kpi-tile-body'); 20551 } 20552 20553 selectorCallback = callback => { 20554 const $graph = $('<div class="kpi-tryouts-stacked-bar-graph"></div>'); 20555 $graph.appendTo(this.body); 20556 return callback($graph.get(0)); 20557 }; 20558 20559 appendSectionLabel(label) { 20560 this.body.append(`<h3 class="subheader">${label}</h3>`); 20561 } 20562 20563 createTile() { 20564 const { columns, rows, tileId, tooltip, title, controls, indicatorList, selector } = this; 20565 20566 const $tile = $(`<div class="kpi-tile${this.className ? ' ' + this.className : ''}"></div>`); 20567 $tile.addClass(`cols-${columns} ${rows ? `rows-${rows}` : ''}`); 20568 if (tileId) $tile.attr('id', tileId); 20569 20570 const $headerGroup = $('<div class="header-group"></div>'); 20571 if (tooltip) $headerGroup.append(`<a href="#" data-tooltip="${tooltip}"></a>`); 20572 $headerGroup.append(`<h3 class="title">${title}</h3>`); 20573
20574 if (controls.length > 0) { 20575 const controlLinks = controls.map(c => `<a href="#" data-control="${c}"></a>`).join('\n'); 20576 $headerGroup.append(`<div data-controls>${controlLinks}</div>`); 20577 } 20578 20579 let $indicators = $('<ul data-indicators></ul>'); 20580 if (indicatorList.length > 0) { 20581 const $indicatorItems = indicatorList.map(ind => $('<li>').text(ind)); 20582 $indicators.append($indicatorItems); 20583 } 20584 20585 $('<header></header>').append($headerGroup).append($indicators).appendTo($tile); 20586 20587 $tile.append('<div class="kpi-tile-body"></div>'); 20588 20589 $(selector).append($tile); 20590 this.$element = $tile; 20591 } 20592} 20593 20594KpiTile.setIndicators = (tileId, indicators) => { 20595 const $tile = $(tileId); 20596 const $tileIndicators = $tile.find('[data-indicators]'); 20597 if ($tileIndicators.length === 0) { 20598 console.warn( 20599 `KpiTile: No elements found with data-indicators attribute. Selector: ${this.selector}` 20600 ); 20601 return; 20602 } 20603 if (typeof indicators === 'string') indicators = [indicators]; 20604 20605 $tileIndicators.each((i, slot) => { 20606 const $slot = $(slot); 20607 $slot.empty(); 20608 indicators.forEach(ind => $slot.append(`<li>${ind}</li>`)); 20609 }); 20610}; 20611 20612KpiTile.appendTooltip = selector => { 20613 $(selector) 20614 .find('[data-tooltip]') 20615 .each((i, el) => { 20616 const $el = $(el); 20617 const tooltipText = $el.data().tooltip; 20618 if (!tooltipText) return; 20619 $el.append('<i class="fas fa-circle-question"></i>'); 20620 }); 20621}; 20622 20623KpiTile.appendControls = selector => { 20624 const $controlsContainer = $(selector).find('[data-controls]'); 20625 const $controlsContainerClone = $controlsContainer.clone(); 20626 20627 $controlsContainerClone.children().each((i, el) => { 20628 const $el = $(el); 20629 $el.on('click', e => e.preventDefault()); 20630 20631 const control = $el.data().control; 20632 switch (control) { 20633 case 'options': 20634 $el.append('<i class="fas fa-sliders"></i>'); 20635 break; 20636 case 'expand': 20637 $el.append('<i class="fas fa-expand"></i>'); 20638 break; 20639 case 'external-link': 20640 // $el.append('<i class="fas fa-arrow-up-right-from-square"></i>'); 20641 $el.remove(); 20642 break; 20643 default: 20644 break; 20645 } 20646 }); 20647 20648 $controlsContainer.replaceWith($controlsContainerClone); 20649}; 20650 20651KpiTile.initTileMarkup = selector => { 20652 KpiTile.appendControls(selector); 20653}; 20654 20655KpiTile.initMarkup = () => { 20656 // This function iterates through each tile and element to initialize the tooltip 20657 function initTooltip(tileOrElement) { 20658 if (!tileOrElement.tooltip || !tileOrElement.selector) return; 20659 const { tooltip, selector, isTile } = tileOrElement; 20660 20661 if (!tooltip) { 20662 console.warn('initTooltip: tooltip is required.'); 20663 } 20664 20665 if ($(selector).find('[data-tooltip]').length) { 20666 $(selector).find('[data-tooltip]').remove(); 20667 } 20668 20669 const $tooltip = $( 20670 `<a href="#" data-tooltip="${tooltip}"><i class='fas fa-circle-question'></i></a>` 20671 ) 20672 .hover( 20673 function () { 20674 $('<p class="kpi-tile-tooltip"></p>').text(tooltip).appendTo('body').show(); 20675 }, 20676 function () { 20677 $('.kpi-tile-tooltip').remove(); 20678 } 20679 ) 20680 .mousemove(function (e) { 20681 const left = e.pageX + 20; 20682 const top = e.pageY + 10; 20683 $('.kpi-tile-tooltip').css({ top, left }); 20684 }) 20685 .click(function (e) { 20686 e.preventDefault(); 20687 }); 20688 20689 if (isTile) { 20690 $(selector).find('.header-group').prepend($tooltip); 20691 return; 20692 } 20693 if ($(selector).find('.subheader-group').length) { 20694 $(selector).find('.subheader-group').prepend($tooltip); 20695 return; 20696 } 20697 console.warn('initTooltip: selector not found. Element =>', selector); 20698 } 20699 20700 Object.keys(KpiDashboardTiles).forEach(tileName => { 20701 const tile = KpiDashboardTiles[tileName]; 20702 initTooltip({ ...tile, isTile: true }); 20703 20704 tile.elements.forEach(element => { 20705 // Sortable stats tooltips handles in a specific way 20706 if (element.type === KpiTypes.TILE_ELEMENT.SORTABLE_STATS) return; 20707 20708 initTooltip({ ...element, isTile: false }); 20709 }); 20710 }); 20711 20712 $('[data-tile]').each((i, tile) => { 20713 KpiTile.initTileMarkup(tile); 20714 }); 20715}; 20716 20717KpiTile.attachTooltip = parentSelector => { 20718 $(parentSelector) 20719 .find('[data-tooltip]') 20720 .each((i, el) => { 20721 const $el = $(el);
20722 const tooltipText = $el.data().tooltip; 20723 if (!tooltipText) return; 20724 20725 $el.hover( 20726 function () { 20727 $('<p class="kpi-tile-tooltip"></p>').text(tooltipText).appendTo('body').show(); 20728 }, 20729 function () { 20730 $('.kpi-tile-tooltip').remove(); 20731 } 20732 ).mousemove(function (e) { 20733 const left = e.pageX + 20; 20734 const top = e.pageY + 10; 20735 $('.kpi-tile-tooltip').css({ top, left }); 20736 }); 20737 $el.click(function (e) { 20738 e.preventDefault(); 20739 }); 20740 }); 20741}; 20742 20743// TODO: Consolidate tooltip init. functions to use this. This is a simpler pattern that makes more sense to use over the rest. 20744KpiTile.setTooltipSimply = (selector, text) => { 20745 const $tooltip = $(selector); 20746 20747 // if tooltip has an icon already, skip, else add it 20748 if (!$tooltip.find('i').length) { 20749 $tooltip.prepend("<i class='fas fa-circle-question'></i>"); 20750 } 20751 20752 $tooltip 20753 .hover( 20754 function () { 20755 $('<p class="kpi-tile-tooltip"></p>').text(text).appendTo('body').show(); 20756 }, 20757 function () { 20758 $('.kpi-tile-tooltip').remove(); 20759 } 20760 ) 20761 .mousemove(function (e) { 20762 const left = e.pageX + 20; 20763 const top = e.pageY + 10; 20764 $('.kpi-tile-tooltip').css({ top, left }); 20765 }); 20766 $tooltip.click(function (e) { 20767 e.preventDefault(); 20768 }); 20769}; 20770 20771KpiTile.spotlightTiles = {}; 20772 20773KpiTile.spotlightTiles.setIndicators = indicatorList => { 20774 $('#kpi-spotlight-page ul[data-indicators]').each((i, el) => { 20775 const $indicatorList = $(el); 20776 $indicatorList.empty(); 20777 [...indicatorList].forEach(ind => $indicatorList.append(`<li>${ind}</li>`)); 20778 }); 20779}; 20780 20781 20782; 20783////pf: javascript/stats/dashboard-chart.js 20784// eslint-disable-next-line no-unused-vars 20785class DashboardChart { 20786 constructor(props) { 20787 this.selector = props.selector; 20788 this.data = props.data; 20789 20790 this.init = this.init.bind(this); 20791 this.setScrollableDimensions = this.setScrollableDimensions.bind(this); 20792 this.setDimensions = this.setDimensions.bind(this); 20793 this.draw = this.draw.bind(this); 20794 this.redraw = this.redraw.bind(this); 20795 this.redrawOnResize = this.redrawOnResize.bind(this); 20796 this.stopRedrawOnResize = this.stopRedrawOnResize.bind(this); 20797 this.prepareGraph = this.prepareGraph.bind(this); 20798 this.setSVG = this.setSVG.bind(this); 20799 20800 this.setXAxisForBars = this.setXAxisForBars.bind(this); 20801 this.setYAxisForBars = this.setYAxisForBars.bind(this); 20802 } 20803 20804 margin = { top: 35, right: 20, bottom: 90, left: 50 }; 20805 MIN_HEIGHT = 550; 20806 MAX_HEIGHT = 700; 20807 viewboxYPadding = 0; 20808 graphClass = ''; 20809 colors = KpiUtils.colors; 20810 xDomain = []; 20811 yDomain = []; 20812 20813 init() { 20814 this.draw(); 20815 this.redrawOnResize(); 20816 } 20817 20818 setDimensions(dimensions) { 20819 const { top, right, bottom, left } = this.margin; 20820 this.width = dimensions.width; 20821 this.height = 20822 this.height || Math.max(this.MIN_HEIGHT, Math.min(this.MAX_HEIGHT, dimensions.height)); 20823 this.innerHeight = this.height - top - bottom; 20824 this.innerWidth = this.width - left - right; 20825 } 20826 20827 setScrollableDimensions(dimensions) { 20828 const { top, right, bottom, left } = this.margin; 20829 let minWidth = 60 * this.data.length; 20830 this.width = Math.max(dimensions.width, minWidth); 20831 $(this.selector).css({ width: `${this.width}px` }, { 'min-width': `${this.width}px` }); 20832 // selector can scroll if overflow 20833 $(this.selector) 20834 .parent() 20835 .css('overflow-x', dimensions.width < minWidth ? 'scroll' : 'hidden'); 20836 this.height = 20837 this.height || Math.max(this.MIN_HEIGHT, Math.min(this.MAX_HEIGHT, dimensions.height)); 20838 this.innerHeight = this.height - top - bottom; 20839 this.innerWidth = this.width - left - right; 20840 } 20841 20842 draw() { 20843 throw new Error('draw() must be implemented'); 20844 } 20845 20846 redraw(callback) { 20847 clearTimeout(this.redrawTimeout); 20848 this.redrawTimeout = setTimeout(() => { 20849 if (callback) callback(); 20850 this.draw(); 20851 }, 250); 20852 } 20853 20854 redrawOnResize(callback) { 20855 this.resizeCallback = () => this.redraw(callback); 20856 window.addEventListener('resize', this.resizeCallback); 20857 } 20858 20859 stopRedrawOnResize() { 20860 window.removeEventListener('resize', this.resizeCallback); 20861 } 20862 20863 prepareGraph(callback, isScrollable) { 20864 KpiUtils.getElementDimensions(this.selector, dimensions => { 20865 if (isScrollable) { 20866 this.setScrollableDimensions(dimensions); 20867 } else { 20868 this.setDimensions(dimensions); 20869 } 20870 20871 $(this.selector).empty(); 20872 this.setSVG(); 20873 20874 callback(); 20875 }); 20876 } 20877 20878 setSVG() { 20879 $(this.selector).addClass(`${this.graphClass} kpi-chart`); 20880 this.svg = d3 20881 .select(this.selector) 20882 .append('svg') 20883 .attr('width', '100%') 20884 .attr('viewBox', `0 0 ${this.width} ${this.height + this.viewboxYPadding}`) 20885 .attr('preserveAspectRatio', 'xMinYMin meet') 20886 .append('g'); 20887 } 20888 20889 /** 20890 * Sets the x-axis for a bar chart, with rotated labels 20891 * @param {number} translateYAdjustment - moves the x-axis up or down 20892 * @param {boolean} removePathDomain - removes the line at the bottom of the x-axis if true 20893 */ 20894 setXAxisForBars(translateYAdjustment, removePathDomain) { 20895 this.xAxis = d3.axisBottom(this.xScale).tickSizeOuter(0).tickSizeInner(0);
20896 20897 const LABEL_LINE_HEIGHT = 13; 20898 const LABEL_WIDTH = this.margin.bottom; 20899 const LABEL_HEIGHT = LABEL_LINE_HEIGHT * 3; 20900 const LABEL_ANGLE = 45; 20901 20902 const TRANSLATE_Y = this.height - this.margin.bottom; 20903 20904 const xAxisWrapper = this.svg 20905 .append('g') 20906 .attr('class', 'x-axis') 20907 .attr('transform', `translate(0, ${TRANSLATE_Y})`) 20908 .call(this.xAxis); 20909 xAxisWrapper.selectAll('.tick').select('text').remove(); 20910 20911 const labelTranslateX = (this.xScale.bandwidth() - (LABEL_WIDTH + LABEL_HEIGHT)) / 4; 20912 20913 xAxisWrapper 20914 .selectAll('.tick') 20915 .append('foreignObject') 20916 .attr('width', LABEL_WIDTH) 20917 .attr('height', LABEL_HEIGHT) 20918 .html(d => `<div class="kpi-rotated-label">${d}</div>`) 20919 .style( 20920 'transform', 20921 `translateX(${labelTranslateX}px) 20922 translateY(${this.margin.bottom - translateYAdjustment}px) 20923 rotate(-${LABEL_ANGLE}deg)` 20924 ); 20925 20926 xAxisWrapper.selectAll('.tick').select('line').remove(); 20927 20928 if (removePathDomain) { 20929 xAxisWrapper.select('path.domain').remove(); 20930 } 20931 } 20932 20933 setYAxisForBars(tickCount = 5, xAxisLine = false) { 20934 this.yAxis = d3 20935 .axisLeft(this.yScale) 20936 .tickSizeOuter(0) 20937 .tickSizeInner(-this.innerWidth) 20938 .tickPadding(10) 20939 .tickFormat(KpiUtils.graphTickFormatKM) 20940 .ticks(tickCount); 20941 20942 this.yAxisWrapper = this.svg 20943 .append('g') 20944 .attr('class', 'y-axis-wrapper') 20945 .attr('transform', `translate(${this.margin.left}, ${this.margin.top})`) 20946 .call(this.yAxis); 20947 20948 this.yAxisWrapper.select('path.domain').remove(); 20949 20950 this.yAxisWrapper 20951 .selectAll('text') 20952 .attr('fill', this.colors.dark) 20953 .attr('font-size', '14px') 20954 .attr('letter-spacing', '0.15px') 20955 .attr('font-weight', 'bold') 20956 .attr('text-anchor', 'end'); 20957 20958 this.yAxisWrapper.selectAll('line').attr('class', 'grid-line'); 20959 20960 if (xAxisLine) { 20961 this.yAxisWrapper 20962 .append('line') 20963 .attr('class', 'x-axis-line') 20964 .attr('x1', 0) 20965 .attr('y1', this.yScale(0)) 20966 .attr('x2', this.innerWidth) 20967 .attr('y2', this.yScale(0)) 20968 .attr('stroke', 'black') 20969 .attr('stroke-width', 2); 20970 } 20971 } 20972 20973 destroy() { 20974 if (this.svg) { 20975 this.svg.remove(); 20976 this.svg = null; 20977 } 20978 20979 this.stopRedrawOnResize(); 20980 $(this.selector).empty(); 20981 20982 this.data = null; 20983 this.colors = null; 20984 this.margin = null; 20985 this.width = null; 20986 this.height = null; 20987 this.innerWidth = null; 20988 this.innerHeight = null; 20989 this.xScale = null; 20990 this.yScale = null; 20991 this.xAxis = null; 20992 this.yAxis = null; 20993 this.selector = null; 20994 this.graphClass = null; 20995 this.redrawTimeout = null; 20996 this.resizeCallback = null; 20997 this.viewboxYPadding = null; 20998 this.yAxisWrapper = null; 20999 this.MAX_HEIGHT = null; 21000 this.MIN_HEIGHT = null; 21001 } 21002} 21003 21004 21005; 21006////pf: javascript/stats/donut-chart.js 21007/** 21008 * This is a class that creates a donut chart from a given data set. 21009 * 21010 * It copies heavily from the original pie-gauge, 21011 * and needs to be refactored and consolidated. 21012 */ 21013// eslint-disable-next-line no-redeclare 21014class DonutChart { 21015 DEFAULT_RADIUS = 138; 21016 DEFAULT_STROKE_WIDTH = 41; 21017 21018 // prettier-ignore 21019 defaultColors = { 21020 array: [ 21021 '#35A8E0', 21022 '#00629A', 21023 '#6B82CB', 21024 '#6750A4', 21025 '#66CED6', 21026 '#969696', 21027 '#494949', 21028 '#E2E2E2' 21029 ], 21030 graySet: KpiUtils.colors.light, 21031 graySetLabel: KpiUtils.colors.darkLabel, 21032 negatives: KpiUtils.colors.danger, 21033 }; 21034 21035 constructor({ selector, data, options }) { 21036 this.selector = selector; 21037 this.update({ data, options }); 21038 } 21039 21040 html = () => this.svg.html(); 21041 21042 update({ data = [], options }) { 21043 if ((!data || !data.length) && (!options || options === {})) { 21044 throw new Error('DonutChart: data or options are required.'); 21045 } 21046 if (options.palette !== DonutChart.palette.byPercent) { 21047 // By percent needs to be sorted as it is, otherwise sort by value 21048 this.segments = data.sort((a, b) => b.value - a.value); 21049 } else { 21050 this.segments = data; 21051 } 21052 this.options = options || {}; 21053 this.init(); 21054 } 21055 21056 destroy() { 21057 $(this.selector).empty(); 21058 } 21059 21060 init() { 21061 this.negativeCounter = 0; 21062 this.innerLabel = this.options.innerLabel || ''; 21063 this.innerValue = this.options.innerValue || ''; 21064 this.radius = this.options.radius || this.DEFAULT_RADIUS; 21065 this.strokeWidth = this.options.strokeWidth || this.DEFAULT_STROKE_WIDTH; 21066 this.palette = this.options.palette || 'default'; 21067 this.subLabels = this.options.subLabels || []; // { label: '', value: '' } 21068 this._sizeProportion = this.radius / this.strokeWidth; 21069 this.modifyAncestor();
21070 this.handlePalette(); 21071 this.draw(); 21072 21073 let redrawTimeout = null; 21074 const redraw = () => { 21075 if (redrawTimeout) clearTimeout(redrawTimeout); 21076 redrawTimeout = setTimeout(() => this.draw(), 100); 21077 }; 21078 window.addEventListener('resize', () => redraw()); 21079 21080 const parentPanel = $(this.selector).closest('.kpi-dashboard-panel')[0]; 21081 const panelId = parentPanel ? parentPanel.id : null; 21082 if (panelId) { 21083 onPanelOpen(panelId, () => this.draw()); 21084 } 21085 } 21086 21087 modifyAncestor() { 21088 // if nearest .kpi-tile has only 1 child, add .single-donut class 21089 const $tile = $(this.selector).closest('.kpi-tile-body'); 21090 if ($tile.children().length === 1) { 21091 $tile.addClass('single-donut'); 21092 } 21093 } 21094 21095 handlePalette() { 21096 if (this.palette === DonutChart.palette.byPercent) { 21097 if (this.segments.length !== 2) { 21098 // eslint-disable-next-line no-console 21099 console.warn( 21100 this.selector, 21101 'DonutChart: palette.byPercent requires 2 segments. Using default instead.' 21102 ); 21103 this.palette = 'default'; 21104 return; 21105 } 21106 21107 // reformat segments to be percentages 21108 const total = this.segments[1].value; 21109 const percent = (Math.abs(this.segments[0].value) / total) * 100; 21110 this.segments[0].value = percent; 21111 this.segments[1].value = 100 - percent; 21112 } 21113 } 21114 21115 getArc = ({ color, fraction, fractionOffset, strokeWidth, radius }) => { 21116 const svgRadius = radius - strokeWidth / 2; 21117 return ` 21118 <path class="pie-gauge-arc" 21119 d="${this.describeArc( 21120 radius, 21121 radius, 21122 svgRadius, 21123 fractionOffset * 360, 21124 (fractionOffset + fraction) * 360 21125 )}" 21126 style="stroke:${color}; stroke-width: ${strokeWidth.toFixed(4)}px; fill: transparent;" > 21127 </path> 21128 `; 21129 }; 21130 21131 colorScale(segment, index, isText = false) { 21132 const percentColor = () => 21133 index === 0 21134 ? KpiUtils.getPercentColor(this.segments[0].value) 21135 : isText 21136 ? this.defaultColors.graySetLabel 21137 : this.defaultColors.graySet; 21138 21139 const defaultColor = () => { 21140 const { negatives, graySet, array } = this.defaultColors; 21141 21142 if (segment.value < 0) { 21143 const negativeSegments = this.segments.filter(s => s.value < 0); 21144 const index = negativeSegments.indexOf(segment); 21145 return negatives[index % negatives.length]; 21146 } 21147 21148 if (segment.isGrayed) return graySet; 21149 21150 return array[index % array.length]; 21151 }; 21152 21153 return this.palette === 'byPercent' ? percentColor() : defaultColor(); 21154 } 21155 21156 drawArcsFromSegments = (radius, strokeWidth) => { 21157 const total = this.segments.reduce((acc, s) => acc + Math.abs(s.value) || 0, 0); 21158 21159 const arcs = []; 21160 21161 if (total === 0) { 21162 return [ 21163 this.getArc({ 21164 color: this.defaultColors.graySet, 21165 fraction: 1, 21166 fractionOffset: 0, 21167 strokeWidth, 21168 radius 21169 }) 21170 ]; 21171 } 21172 21173 let offset = 0; 21174 const DIVIDER_FRACTION = 0.005; 21175 const filteredSegments = this.segments.filter((s) => s.value !== 0) 21176 const addDivider = filteredSegments.length > 1; 21177 21178 filteredSegments.forEach((s, i) => { 21179 let fraction = Math.abs(s.value) / total; 21180 if (addDivider) fraction -= DIVIDER_FRACTION; 21181 21182 // Since we are filtering out 0 value segments we still need the original index for colors 21183 const colorIndex = this.segments.findIndex(seg => seg.name === s.name) 21184 arcs.push( 21185 this.getArc({ 21186 color: this.colorScale(s, colorIndex), 21187 fraction, 21188 fractionOffset: offset, 21189 strokeWidth, 21190 radius, 21191 }) 21192 ); 21193 //^ Add a divider between segments 21194 if (addDivider) { 21195 arcs.push( 21196 this.getArc({ 21197 color: "#FFFFFF", 21198 fraction: DIVIDER_FRACTION, 21199 fractionOffset: offset + fraction, 21200 strokeWidth, 21201 radius, 21202 }) 21203 ); 21204 offset += DIVIDER_FRACTION 21205 } 21206 offset += fraction 21207 }); 21208 21209 return arcs.join('\n'); 21210 }; 21211 21212 drawLegend = () => { 21213 const determineColor = (segment, index) => { 21214 if (segment.value === 0) { 21215 return this.defaultColors.graySetLabel; 21216 } 21217 if (segment.isGrayed) { 21218 return this.defaultColors.graySet; 21219 } 21220 return this.colorScale(segment, index, true); 21221 }; 21222 21223 const legend = this.segments 21224 .map((s, i) => { 21225 const subLabels = (s.subLabels || []).map( 21226 sublabel => 21227 `<div class='donut-chart__legend__sublabel'>${sublabel.label} <b>${sublabel.value}</b></div>` 21228 ); 21229 21230 return ` 21231 <div class='metric-key__child'> 21232 <div class='donut-chart__legend__label label'>${s.name}</div> 21233 <div class='donut-chart__legend__value value' style='color: ${determineColor(s, i)};'> 21234 ${s.formattedValue ?? s.value} 21235 </div> 21236 ${subLabels.join('')} 21237 </div> 21238 `; 21239 }) 21240 .join(''); 21241 21242 $(this.selector).css('padding-bottom', `${20}px`); 21243 21244 return legend; 21245 }; 21246
21247 drawInnerMetric = radius => { 21248 let PADDING = 10, 21249 LABEL_HEIGHT = 21, 21250 OFFSET_CENTER_PX = 0.55 * (radius * 2), 21251 SUBLABEL_HEIGHT = 14; 21252 21253 const isMultiLine = KpiUtils.isJson(this.innerLabel); 21254 const hasSublabels = this.subLabels.length > 0; 21255 21256 if (hasSublabels) { 21257 OFFSET_CENTER_PX = 0.5 * (radius * 2); 21258 } 21259 21260 const getYPositions = () => { 21261 let offsetByPadding = OFFSET_CENTER_PX - PADDING / 2; 21262 if (hasSublabels) { 21263 offsetByPadding -= 5; 21264 } 21265 const yUpper = isMultiLine ? offsetByPadding - LABEL_HEIGHT / 2 : offsetByPadding; 21266 let yLower = yUpper + PADDING + LABEL_HEIGHT; 21267 21268 if (hasSublabels && isMultiLine) { 21269 const LINE_SPACE = 5; 21270 const lines = JSON.parse(this.innerLabel); 21271 yLower += lines.length * LABEL_HEIGHT - LABEL_HEIGHT - LINE_SPACE; 21272 } 21273 return { yUpper, yLower }; 21274 }; 21275 21276 const { yUpper, yLower } = getYPositions(); 21277 21278 const drawLabel = () => { 21279 const LINE_SPACE = 8; 21280 const y = hasSublabels ? yUpper - LABEL_HEIGHT - LINE_SPACE : yLower; 21281 if (isMultiLine) { 21282 const labels = JSON.parse(this.innerLabel); 21283 const labelViews = labels.map( 21284 (label, i) => 21285 `<text x='${radius}' y='${y + i * LABEL_HEIGHT 21286 }' class='inner-label'>${label}</text>` 21287 ); 21288 return labelViews.join(''); 21289 } else { 21290 return `<text x='${radius}' y='${y}' class='inner-label'>${this.innerLabel}</text>`; 21291 } 21292 }; 21293 21294 const drawValue = () => { 21295 const y = hasSublabels ? yLower - 5 : yUpper; 21296 return `<text x='${radius}' y='${y}' class='inner-value'>${this.innerValue || 0}</text>`; 21297 }; 21298 21299 const drawSublabels = () => { 21300 if (this.subLabels.length > 0) { 21301 const sublabelViews = this.subLabels.map( 21302 (sublabel, i) => 21303 `<text x='${radius}' y='${yLower + SUBLABEL_HEIGHT + i * SUBLABEL_HEIGHT 21304 }' class='inner-sublabel'>${sublabel.label} <tspan font-weight='bold'>${sublabel.value 21305 }</tspan> 21306 </text>` 21307 ); 21308 return sublabelViews.join(''); 21309 } 21310 }; 21311 21312 const labelHtml = drawLabel() || ''; 21313 const subLabelsHtml = drawSublabels() || ''; 21314 const valueHtml = drawValue() || ''; 21315 21316 return [labelHtml, valueHtml, subLabelsHtml].join('\n'); 21317 }; 21318 21319 handleResize() { 21320 const parentWidth = $(this.selector).parent().width(); 21321 this.adjusted_radius = null; 21322 this.adjusted_stroke_width = null; 21323 if (parentWidth < this.radius * 2) { 21324 this.adjusted_radius = parentWidth / 2; 21325 this.adjusted_stroke_width = this.adjusted_radius / this._sizeProportion; 21326 } 21327 } 21328 21329 draw() { 21330 $(this.selector).empty(); 21331 this.handleResize(); 21332 21333 let radius = this.adjusted_radius || Number(this.radius); 21334 let strokeWidth = this.adjusted_stroke_width || Number(this.strokeWidth); 21335 21336 const diameter = (radius * 2).toFixed(4); 21337 21338 const showLegend = this.type !== 'attendance-gauge'; // TODO: show legend should be a prop 21339 21340 this.svg = $(` 21341 <div class="donut-chart" style="height: ${diameter}px;"> 21342 <svg viewPort="0 0 100 100" style="width: ${diameter}px; height: ${diameter}px;"> 21343 ${this.drawArcsFromSegments(radius, strokeWidth)} 21344 ${this.drawInnerMetric(radius)} 21345 </svg> 21346 </div> 21347 ${showLegend ? `<div class='metric-key'>${this.drawLegend()}</div>` : ''} 21348 `); 21349 $(this.selector).html(this.svg); 21350 } 21351 21352 describeArc(x, y, radius, startAngle, endAngle) { 21353 const { polarToCartesian, truncateNumber } = DonutChart; 21354 const start = polarToCartesian(x, y, radius, endAngle); 21355 const end = polarToCartesian(x, y, radius, startAngle); 21356 const largeArcFlag = endAngle - startAngle <= 180 ? '0' : '1'; 21357 const d = [ 21358 'M', 21359 truncateNumber(start.x), 21360 truncateNumber(start.y), 21361 'A', 21362 radius, 21363 radius, 21364 0, 21365 largeArcFlag, 21366 0, 21367 truncateNumber(end.x), 21368 truncateNumber(end.y) 21369 ].join(' '); 21370 21371 return d; 21372 } 21373} 21374 21375// TODO: The following functions are repeats. Consolidate them. 21376DonutChart.truncateNumber = (num) => 21377 num.toString().substring(0, Math.floor(num).toString().length + 5); 21378 21379DonutChart.polarToCartesian = (centerX, centerY, radius, angleInDegrees) => {
21380 const angleInRadians = ((angleInDegrees - 90) * Math.PI) / 180.0; 21381 return { 21382 x: centerX + radius * Math.cos(angleInRadians), 21383 y: centerY + radius * Math.sin(angleInRadians), 21384 }; 21385}; 21386 21387DonutChart.palette = { 21388 byPercent: "byPercent", 21389}; 21390 21391 21392; 21393////pf: javascript/stats/progress-stat.js 21394// eslint-disable-next-line no-redeclare 21395class ProgressStat { 21396 constructor({ selector, data, percent, options }) { 21397 // * OPTIONS 21398 const { 21399 img, 21400 title, 21401 link, 21402 formattedValue, 21403 formattedValueType, 21404 useEndCapLayout, 21405 flipColors, 21406 restructuredOrder 21407 } = options; 21408 21409 this.img = img; 21410 this.title = title; 21411 this.link = link || null; 21412 21413 this.useEndCapLayout = useEndCapLayout; 21414 this.formattedValue = formattedValue; 21415 this.formattedValueType = formattedValueType; 21416 21417 this.selector = selector; // Optional, set by createGroup if not provided (or not appended) 21418 this.data = data; 21419 this.percent = percent; 21420 this._isMultiVariable = this.data.length > 2; 21421 this.flipColors = flipColors; 21422 this.restructuredOrder = restructuredOrder; 21423 this.init(); 21424 } 21425 21426 _html = null; 21427 maxPercent = 0; 21428 percentExceededLabel = null; 21429 initialized = false; 21430 21431 init() { 21432 this.measureData(); 21433 this._html = this.draw(); 21434 this.initialized = true; 21435 if (this.selector) { 21436 $(this.selector).append(this._html); 21437 } 21438 } 21439 21440 get html() { 21441 return this._html.clone().wrap('<div>').parent().html(); 21442 } 21443 21444 /** 21445 * Need to determine the data|max to measure the bars. 21446 */ 21447 measureData = () => { 21448 this.maxPercent = this.data.reduce((acc, i) => Math.max(acc, i.percent || 0), 0); 21449 21450 this.percentExceededLabel = 21451 this.maxPercent > 100 21452 ? this.data.find(i => i.percent === undefined)?.name || 'Budget' 21453 : null; 21454 }; 21455 21456 /** 21457 * Draw the entire element. 21458 */ 21459 draw = () => { 21460 const { $bars, $labels } = this.createBarsAndLabels(); 21461 const $html = $('<div class="kpi-progress"></div>'); 21462 21463 const $img = this.createImage(); 21464 if ($img != null) $html.append($img); 21465 21466 const $content = $('<div class="kpi-progress__content"></div>') 21467 .append(this.createHeader()) 21468 .append($bars) 21469 .append($labels); 21470 $html.append($content); 21471 21472 const $indicator = this.createEndCap(); 21473 if ($indicator != null) $html.append($indicator); 21474 21475 return $html; 21476 }; 21477 21478 /** 21479 * Takes a percent value for a bar and formats it properly for the bar width. 21480 * @param {number} percent 21481 * @returns {number} The formatted percent to use for the bar width. 21482 */ 21483 formatDataPercent = percent => { 21484 if (percent === undefined) return undefined; 21485 // If the max percent is greater than 100 measure against that 21486 if (this.maxPercent > 100) { 21487 percent = (percent / this.maxPercent) * 100; 21488 } 21489 if (percent > 100) return 100; 21490 return Math.round(percent); 21491 }; 21492 21493 sortByPercent = data => { 21494 var sortedData = data.slice(); 21495 sortedData.sort((a, b) => { 21496 if (!a.percent && a.percent != 0) return 1; 21497 if (!b.percent && b.percent != 0) return -1; 21498 const percentA = a.percent; 21499 const percentB = b.percent; 21500 if (percentA <= percentB) return 1; 21501 if (percentA > percentB) return -1; 21502 return 0; 21503 }); 21504 return sortedData; 21505 }; 21506 21507 getColor = (colorClass, index) => { 21508 if (!this._isMultiVariable) return colorClass; 21509 const isDark = this.flipColors ? index > 0 : index === 0; 21510 return isDark ? `${colorClass}-dark` : colorClass; 21511 }; 21512 21513 createBarsAndLabels = () => { 21514 const $bars = $('<div data-bars></div>'); 21515 const $labels = $('<ul class="kpi-progress__label-group"></ul>'); 21516 const data = this.data; 21517 data.sort((a, b) => { 21518 const budgetA = a.percent || a.percent === 0 ? 1 : -1; 21519 const budgetB = b.percent || b.percent === 0 ? 1 : -1; 21520 if (budgetA < budgetB) return 1; 21521 if (budgetA > budgetB) return -1; 21522 return 0; 21523 }); 21524 const sortedData = this.sortByPercent(data); 21525 21526 const usesPercent = data.some(b => b.percent !== undefined); 21527 21528 $bars.append('<div data-bar></div>'); 21529 21530 if (usesPercent) { 21531 let colorClass = KpiUtils.percentToColorClass(this.maxPercent); 21532 21533 // labels 21534 data.forEach(barValue => { 21535 const barIndex = sortedData.findIndex(i => i.name === barValue.name); 21536 const labelColor = 21537 barValue.percent === undefined ? '' : this.getColor(colorClass, barIndex); 21538 $labels.append( 21539 `<li class="${`li-${labelColor}`}"> 21540 ${barValue.name}: <b>${barValue.formattedValue}</b> 21541 </li>`
21542 ); 21543 }); 21544 21545 sortedData.forEach((barValue, i) => { 21546 const percent = this.formatDataPercent(barValue.percent); 21547 if (percent !== undefined) { 21548 const barColor = this.getColor(colorClass, i); 21549 const $bar = $( 21550 `<div data-bar style="width: ${percent}%" 21551 class="${barColor} ${barValue.value < 0 ? 'has-negative' : ''}"></div>` 21552 ); 21553 const $divider = $( 21554 `<div style="width: ${percent}%;" 21555 class="data-bar-spacer ${barValue.value < 0 ? 'has-negative' : ''}"></div>` 21556 ); 21557 $bars.append($divider).append($bar); 21558 } 21559 }); 21560 21561 if (this.maxPercent > 110) { 21562 // 110 -> tail sticking out on the right 21563 this.createExceededIndicator($bars); 21564 } 21565 } else { 21566 // eslint-disable-next-line no-console 21567 console.warn(`${this.selector} Progress loaded without any percent values`); 21568 } 21569 21570 return { $bars, $labels }; 21571 }; 21572 21573 createExceededIndicator = $barsContainer => { 21574 const exceededLabel = this.percentExceededLabel; 21575 21576 const $exceeded = $( 21577 `<div data-bar class="is-exceeded" style="width: ${(100 * 100) / this.maxPercent}%"> 21578 <div class="indicator"> 21579 <div class="indicator__inner"></div> 21580 </div> 21581 </div>` 21582 ); 21583 $barsContainer.append($exceeded); 21584 21585 if (exceededLabel == null) return; 21586 21587 const $indicator = $exceeded.find('.indicator'); 21588 $indicator.hover( 21589 function () { 21590 $('<p class="kpi-tile-tooltip"></p>') 21591 .text(`100% of ${exceededLabel}`) 21592 .appendTo('body') 21593 .show(); 21594 const left = $indicator.offset().left + $indicator.width(); 21595 const top = $indicator.offset().top - $indicator.height() * 2; 21596 $('.kpi-tile-tooltip').css({ top, left }); 21597 }, 21598 function () { 21599 $('.kpi-tile-tooltip').remove(); 21600 } 21601 ); 21602 }; 21603 21604 createEndCap = () => { 21605 let { formattedValue, formattedValueType } = this; 21606 21607 if (!this.useEndCapLayout) { 21608 if (!formattedValue) return null; 21609 if (typeof formattedValue === 'string' && formattedValue.length === 0) return null; 21610 } 21611 21612 if (this.useEndCapLayout) { 21613 formattedValue = formattedValue || ' '; 21614 formattedValueType = formattedValueType || 'even'; 21615 } 21616 21617 let $icon = null; 21618 if (!formattedValueType) return null; 21619 switch (formattedValueType) { 21620 case 'positive': 21621 $icon = '<i class="fas fa-arrow-up"></i>'; 21622 break; 21623 case 'negative': 21624 $icon = '<i class="fas fa-arrow-down"></i>'; 21625 break; 21626 case 'even': 21627 $icon = ' '; 21628 break; 21629 default: 21630 if (typeof formattedValueType === 'string' && formattedValueType.length > 0) { 21631 // eslint-disable-next-line no-console 21632 console.warn( 21633 `ProgressStat: formattedValueType "${formattedValueType}" is not supported. Supported types are: "positive", "negative", "even" or null.` 21634 ); 21635 } 21636 return null; 21637 } 21638 21639 const $html = $('<div class="kpi-progress__end-cap"></div>'); 21640 const $value = $(`<div class="kpi-progress__end-cap__value ${formattedValueType}"></div>`); 21641 $value.append($icon).append(formattedValue); 21642 $html.append($value); 21643 21644 return $html; 21645 }; 21646 21647 createImage = () => 21648 this.img && 21649 ` 21650 <div class="kpi-progress__img-wrapper"> 21651 <img src="${this.img}" alt="alt_text"> 21652 </div> 21653 `; 21654 21655 createHeader = () => { 21656 const { title, link } = this; 21657 const $header = $('<div class="kpi-progress__header"></div>'); 21658 if (!link) $header.text(title); 21659 else $header.append(`<a href="${link}">${title}</a>`); 21660 return $header; 21661 }; 21662 21663 destroy() { 21664 this.data = null; 21665 this._html = null; 21666 } 21667} 21668 21669/** 21670 * Creates a Progress Stat group, which is a collection of Progress Stats. 21671 */ 21672ProgressStat.createGroup = ({ 21673 selector, 21674 title, 21675 progressStats, 21676 sorting, 21677 tooltip, 21678 handleSort, 21679 options 21680}) => { 21681 // Cleanup any existing progress stats 21682 ProgressStat.cleanupProgressStats(selector); 21683 21684 const $selector = $(selector); // The container element 21685 $selector.addClass('kpi-progress-group'); 21686 21687 // Do not render if already rendered 21688 if ($selector.find('.subheader-group').length === 0) { 21689 if (title || tooltip || handleSort != null) { 21690 // Render subheader, a container for title, tooltip, and sorting controls 21691 const $subheaderGroup = $('<div class="subheader-group"></div>'); 21692 if (tooltip) { 21693 $subheaderGroup.append( 21694 `<a href="#" data-tooltip="${tooltip}"><i class='fas fa-circle-question'></i></a>` 21695 ); 21696 } 21697 if (title) { 21698 $subheaderGroup.append(`<h3>${title}</h3>`); 21699 } 21700 $selector.append($subheaderGroup); 21701 } 21702 } 21703 21704 // Do not rerender sorting controls 21705 let hasSortingControls = $selector.find('.kpi-tile__sorting').length > 0;
21706 if (handleSort != null && sorting && !hasSortingControls) { 21707 ProgressStat.addSort({ 21708 $progressStatGroup: $selector.find('.subheader-group'), 21709 handleSort 21710 }); 21711 hasSortingControls = true; 21712 } 21713 if (tooltip) KpiTile.attachTooltip($selector); 21714 21715 // Form the list of progress stats 21716 const $list = $selector.find('.kpi-progress-list').length 21717 ? $selector.find('.kpi-progress-list') 21718 : $('<div class="kpi-progress-list"></div>'); 21719 21720 $list.find('.kpi-progress').remove(); // Remove all existing progress stats 21721 21722 // * Allow subheader to build first before stopping 21723 if (!progressStats || progressStats.length === 0) { 21724 return; 21725 } 21726 21727 // If `useEndCapLayout` is set explicitly, or if any of the progress stats have a formatted value, use the end cap layout. This layout has the arrow and value on the right side of the progress stat. 21728 const shouldUseEndCapLayout = 21729 options?.useEndCapLayout || 21730 progressStats.some(progressStat => { 21731 const { options } = progressStat; 21732 return options && options.formattedValue; 21733 }); 21734 21735 // Render each progress stat 21736 progressStats.forEach(progStat => { 21737 if (!progStat.initialized) { 21738 progStat.options = { 21739 ...progStat.options, 21740 ...options, 21741 useEndCapLayout: shouldUseEndCapLayout 21742 }; 21743 const instance = new ProgressStat({ ...progStat, selector: $list }); 21744 if (!AllProgressStats[selector]) { 21745 AllProgressStats[selector] = []; 21746 } 21747 AllProgressStats[selector].push(instance); 21748 } else { 21749 $list.append(progStat.html); 21750 } 21751 }); 21752 21753 $selector.append($list); 21754 21755 return $selector; 21756}; 21757 21758/** 21759 * Adds sorting controls to a Progress Stat group. 21760 * 21761 * @param {Object} params 21762 * @param {jQuery} params.$element 21763 * @param {function} params.handleSort 21764 */ 21765ProgressStat.addSort = ({ $progressStatGroup, handleSort }) => { 21766 // Add sorting control if it doesn't exist 21767 if ($progressStatGroup.find('.kpi-tile__sorting').length === 0) { 21768 $progressStatGroup.append(` 21769 <div class="kpi-tile__sorting"> 21770 <a href="#" data-next=""> 21771 <i class="fas fa-arrow-up"></i> 21772 High 21773 </a> 21774 <a href="#" data-next="showTopResults" style="display: none;"> 21775 <i class="fas fa-arrow-down"></i> 21776 Low 21777 </a> 21778 </div> 21779 `); 21780 } 21781 21782 /** 21783 * Enables or disables the sorting control 21784 * @param {jQuery} $a - The sorting control anchor element 21785 * @param {boolean} enable - Whether to enable or disable the control 21786 */ 21787 const enableControl = ($a, enable = true) => { 21788 const pointerEvents = enable ? 'auto' : 'none'; 21789 const opacity = enable ? '1' : '0.5'; 21790 $a.css('pointer-events', pointerEvents); 21791 $progressStatGroup 21792 .find('.kpi-tile__sorting') 21793 .css({ 'pointer-events': pointerEvents, opacity }); 21794 }; 21795 21796 $progressStatGroup.on('click', '.kpi-tile__sorting > a', async function (e) { 21797 e.preventDefault(); 21798 const $a = $(this); 21799 21800 enableControl($a, false); 21801 $a.hide().siblings().show(); 21802 21803 const showTopResults = $a.data('next') === 'showTopResults'; 21804 await handleSort(showTopResults); 21805 21806 enableControl($a); 21807 }); 21808}; 21809 21810ProgressStat.cleanupProgressStats = selector => { 21811 if (AllProgressStats[selector]) { 21812 AllProgressStats[selector].forEach(progressStat => { 21813 progressStat.destroy(); 21814 }); 21815 AllProgressStats[selector] = []; 21816 } 21817}; 21818 21819const AllProgressStats = {}; // Stores all progress stats to reference later 21820 21821 21822; 21823////pf: javascript/stats/percent-key.js 21824// eslint-disable-next-line no-redeclare 21825const PercentKey = {}; 21826 21827PercentKey.html = ` 21828 <div class="percentage-legend"> 21829 <div class="percentage-legend__label"> 21830 Percent of Budget Met: 21831 </div> 21832 <ul class="percentage-legend__items"> 21833 <li class="percentage-color-00">0</li> 21834 <li class="percentage-color-20">20%</li> 21835 <li class="percentage-color-40">40%</li> 21836 <li class="percentage-color-60">60%</li> 21837 <li class="percentage-color-80">80%+</li> 21838 </ul> 21839 </div> 21840`; 21841 21842PercentKey.initializeAll = (selector = '[percent-key]') => { 21843 $(selector).each((i, el) => { 21844 $(el).replaceWith(PercentKey.html); 21845 }); 21846}; 21847 21848 21849; 21850////pf: javascript/stats/stacked-bars-2.js 21851/** 21852 * Stacked Bar Graph 2 21853 * @param {string} selector 21854 * @param {array} data 21855 * @param {object} options 21856 * @param {boolean} options.useSmallLabels - Whether or not to shorten the labels 21857 * @param {boolean} options.useMonthsFormat - Whether or not to use the months format 21858 * @param {array} options.legend - The legend for the graph 21859 */ 21860// eslint-disable-next-line no-redeclare, no-unused-vars, no-undef 21861class StackedBarGraph2 extends DashboardChart { 21862 constructor({ selector, data, options = {}, params = {} }) { 21863 super({ selector, data }); 21864 try { 21865 if (!data || !data.values || !data.values.length) { 21866 throw new Error('StackedBarGraph2: data is required.'); 21867 } 21868 if (data.values.every(d => d.values.every(value => value === 0))) { 21869 throw new Error('StackedBarGraph2: all values are 0.'); 21870 } 21871 this.data = data; 21872 this.options = options; 21873 this.params = params; 21874 21875 this.init(); 21876 } catch (error) { 21877 // eslint-disable-next-line no-console 21878 console.error(error); 21879 throw error; 21880 } 21881 } 21882 21883 BAR_DIVIDER_HEIGHT = 3; 21884 BAR_PADDING = 0.3; 21885 graphClass = 'stacked-bar-graph-2'; 21886 21887 init() { 21888 this.xDomain = []; 21889 this.yDomain = []; 21890 this.timePeriod = this.params?.timePeriod; 21891 this.margin = { top: 25, right: 20, bottom: 40, left: 60 }; 21892 this.legendItems = null; 21893 this.parseOptions(this.options); 21894 this.dataLength = this.data.values.length; 21895 this.formatData(this.data); 21896 this.draw(); 21897 this.redrawOnResize(); 21898 } 21899 21900 draw() { 21901 this.prepareGraph(() => { 21902 this.setValues();
21903 this.setXAxis(); 21904 this.setYAxis(); 21905 this.drawBars(); 21906 this.drawBarMarkers(); 21907 this.drawOverlay(); 21908 this.prependLegend(); 21909 this.drawBottomLine(); 21910 21911 // after drawing remove 100% height 21912 $(this.selector).css('height', 'auto'); 21913 }, false); 21914 } 21915 21916 prependLegend() { 21917 if (!this.legendItems) return; 21918 if (this.$legend) this.$legend.remove(); 21919 21920 this.$legend = $('<div class="metric-key metric-key-left"></div>'); 21921 this.legendItems.forEach(legendItem => { 21922 const { label, formattedValue } = legendItem; 21923 $(` 21924 <div> 21925 <div class="label">${label}</div> 21926 <div class="value">${formattedValue}</div> 21927 </div> 21928 `).appendTo(this.$legend); 21929 }); 21930 $(this.selector).prepend(this.$legend); 21931 } 21932 21933 parseOptions(options = {}) { 21934 let marginTopStart = 25; 21935 let marginBottomStart = 40; 21936 21937 if (options.legend && options.legend.length > 0) { 21938 this.legendItems = options.legend; 21939 marginTopStart += 75; 21940 } 21941 if (options.useSmallLabels) { 21942 marginBottomStart += 60; 21943 } 21944 if (options.height) { 21945 this.height = options.height; 21946 } 21947 this.margin.top = marginTopStart; 21948 this.margin.bottom = marginBottomStart; 21949 21950 if (options.margin) { 21951 this.margin = { ...this.margin, ...options.margin }; 21952 } 21953 } 21954 21955 formatData = data => { 21956 this.data.values = data.values.map(d => { 21957 const { values } = d; 21958 const _max = Math.max(...values); 21959 const _percentGroup = 21960 this.options.customColor || KpiUtils.getPercentGroup((values[1] / values[0]) * 100); 21961 return { ...d, _percentGroup, _max }; 21962 }); 21963 }; 21964 21965 setValues() { 21966 if (!this.xDomain || !this.xDomain.length) this.xDomain = this.data.values.map(d => d.key); 21967 if (!this.yDomain || !this.yDomain.length) { 21968 const flattenedData = this.data.values.reduce((acc, d) => acc.concat(d.values), []); 21969 this.yDomain = [0, Math.max(...flattenedData)]; 21970 } 21971 this.xScale = d3 21972 .scaleBand() 21973 .domain(this.xDomain) 21974 .padding(this.BAR_PADDING) 21975 .range([0, this.innerWidth]); 21976 this.yScale = d3.scaleLinear().domain(this.yDomain).range([this.innerHeight, 0]); 21977 } 21978 21979 _appendXAxisWrapper({ transform, hideTickText, additionalAttributes = {} }) { 21980 let wrapper = this.svg 21981 .append('g') 21982 .attr('width', this.width) 21983 .attr('class', 'x-axis') 21984 .attr('transform', transform); 21985 for (const [key, value] of Object.entries(additionalAttributes)) { 21986 wrapper = wrapper.attr(key, value); 21987 } 21988 wrapper.call(this.xAxis); 21989 if (hideTickText) { 21990 wrapper.selectAll('.tick').select('text').remove(); 21991 } 21992 return wrapper; 21993 } 21994 21995 _appendLabel({ 21996 wrapper, 21997 labelClass, 21998 labelWidth, 21999 labelHeight, 22000 labelTranslateX, 22001 labelTranslateY, 22002 labelAngle 22003 }) { 22004 wrapper 22005 .selectAll('.tick') 22006 .append('foreignObject') 22007 .attr('width', labelWidth) 22008 .attr('height', labelHeight) 22009 .html(d => `<div class="${labelClass}">${d}</div>`) 22010 .style( 22011 'transform', 22012 `translateX(${labelTranslateX}px) translateY(${labelTranslateY}px) rotate(-${labelAngle}deg)` 22013 ); 22014 wrapper.selectAll('.tick').select('line').remove(); 22015 wrapper.select('path.domain').remove(); 22016 } 22017 22018 setXAxis() { 22019 try { 22020 this.xAxis = d3.axisBottom(this.xScale).tickSizeOuter(0).tickSizeInner(0); 22021 22022 const getTranslateX = (w, h) => (this.xScale.bandwidth() - (w + h)) / 4; 22023 const translateY = this.height - this.margin.bottom; 22024 const labelAngle = 45; 22025 22026 /** 22027 * The default way to display labels 22028 */ 22029 const _useDefaultLabels = () => { 22030 const lineHeight = 13; 22031 const w = this.margin.bottom; 22032 const h = lineHeight * 3; 22033 22034 const xAxisWrapper = this.svg 22035 .append('g') 22036 .attr('width', this.width) 22037 .attr('class', 'x-axis') 22038 .attr('transform', `translate(0, ${translateY})`) 22039 .call(this.xAxis); 22040 xAxisWrapper.selectAll('.tick').select('text').remove(); 22041 22042 xAxisWrapper 22043 .selectAll('.tick') 22044 .append('foreignObject') 22045 .attr('width', w) 22046 .attr('height', h) 22047 .html(d => `<div class="kpi-rotated-label">${d}</div>`) 22048 .style( 22049 'transform', 22050 `translateX(${getTranslateX(w, h)}px) 22051 translateY(${this.margin.bottom - 18}px) 22052 rotate(-${labelAngle}deg)` 22053 ); 22054 22055 xAxisWrapper.selectAll('.tick').select('line').remove(); 22056 xAxisWrapper.select('path.domain').remove(); 22057 }; 22058 22059 /**
22060 * Display labels smaller and at an angle 22061 */ 22062 const _useSmallLabels = () => { 22063 const lineHeight = 9; 22064 const w = this.margin.bottom + 22; 22065 const h = lineHeight * 2; 22066 22067 const xAxisWrapper = this.svg 22068 .append('g') 22069 .attr('width', this.width) 22070 .attr('class', 'x-axis') 22071 .attr('transform', `translate(${0}, ${translateY})`) 22072 .call(this.xAxis); 22073 xAxisWrapper.selectAll('.tick').select('text').remove(); 22074 22075 xAxisWrapper 22076 .selectAll('.tick') 22077 .append('foreignObject') 22078 .attr('width', w) 22079 .attr('height', h) 22080 .html(d => `<div class="kpi-rotated-label chart-small-labels">${d}</div>`) 22081 .style( 22082 'transform', 22083 `translateX(${getTranslateX(w, h) + 4}px) 22084 translateY(${this.margin.bottom - 7}px) 22085 rotate(-${labelAngle}deg)` 22086 ); 22087 22088 xAxisWrapper.selectAll('.tick').select('line').remove(); 22089 xAxisWrapper.select('path.domain').remove(); 22090 }; 22091 22092 /** 22093 * Display labels as time 22094 */ 22095 const _useMonthsFormat = () => { 22096 const periods = KpiTypes.FILTER_TIME_PERIOD; 22097 const _small = this.width < 450; 22098 const xDomain = this.xScale.domain(); 22099 22100 const labelWidth = 40; 22101 const labelCount = KpiUtils.getResponsiveNumTicks( 22102 this.innerWidth, 22103 xDomain.length, 22104 labelWidth 22105 ); 22106 22107 let tickFormat; 22108 let tickValues; 22109 22110 if (this.timePeriod === periods.LIFETIME.value) { 22111 tickValues = xDomain.filter((d, i) => { 22112 let date = new Date(d); 22113 return date.getMonth() === 0; // January is 0 in JavaScript's Date object 22114 }); 22115 tickFormat = d => d3.timeFormat('%Y')(new Date(d)); 22116 } else { 22117 const tickInterval = Math.ceil(xDomain.length / labelCount); 22118 tickValues = xDomain.filter((d, i) => i % tickInterval === 0); 22119 const getTickFormat = (d, i) => { 22120 if (this.timePeriod === periods.LAST_30_DAYS.value) { 22121 return d3.timeFormat('%b')(new Date(d)); 22122 } 22123 if (i % tickInterval === 0) { 22124 return KpiUtils.getTimePeriodTickFormat(this.timePeriod)(new Date(d)); 22125 } 22126 return ''; 22127 }; 22128 tickFormat = getTickFormat; 22129 } 22130 22131 // prettier-ignore 22132 this.xAxis 22133 .tickPadding(10) 22134 .tickValues(tickValues) 22135 .tickFormat(tickFormat); 22136 22137 const xAxisWrapper = this.svg 22138 .append('g') 22139 .attr('class', 'x-axis') 22140 .attr('transform', `translate(${this.margin.left}, ${translateY})`) 22141 .call(this.xAxis); 22142 22143 if (_small) { 22144 xAxisWrapper.selectAll('text').attr('letter-spacing', '-0.15px'); 22145 } 22146 22147 // highlight current month
22148 try { 22149 if (KpiUtils.shouldHighlightXLabel(this.timePeriod)) { 22150 const currentMonth = new Date().getMonth(); 22151 // get from xDomain the index of the date with current month and year 22152 const currentMonthIndex = xDomain.findIndex(d => { 22153 const date = new Date(d); 22154 return ( 22155 date.getMonth() === currentMonth && 22156 date.getFullYear() === new Date().getFullYear() 22157 ); 22158 }); 22159 // highlight the tick with current month 22160 xAxisWrapper 22161 .selectAll('.tick') 22162 .filter((d, i) => i === currentMonthIndex) 22163 .select('text') 22164 .attr('class', 'current-month') 22165 .each(KpiUtils.highlightXLabel); 22166 } 22167 } catch (error) { 22168 // eslint-disable-next-line no-console 22169 console.warn('Error highlighting month', error); 22170 } 22171 }; 22172 22173 // Determined in options 22174 if (this.options.useSmallLabels) { 22175 return _useSmallLabels(); 22176 } 22177 if (this.options.useMonthsFormat) { 22178 return _useMonthsFormat(); 22179 } 22180 return _useDefaultLabels(); 22181 } catch (error) { 22182 // eslint-disable-next-line no-console 22183 console.error(error); 22184 } 22185 } 22186 22187 setYAxis() { 22188 const yAxis = d3 22189 .axisLeft(this.yScale) 22190 .tickSizeOuter(0) 22191 .tickSizeInner(-this.innerWidth) 22192 .tickPadding(10) 22193 .ticks(5) 22194 .tickFormat(KpiUtils.graphTickFormatKM); 22195 22196 const yAxisWrapper = this.svg 22197 .append('g') 22198 .attr('class', 'y-axis') 22199 .attr('transform', `translate(${this.margin.left}, ${this.margin.top})`) 22200 .call(yAxis); 22201 22202 yAxisWrapper.selectAll('line').attr('class', 'grid-line'); 22203 22204 yAxisWrapper 22205 .append('line') 22206 .attr('class', 'x-axis-line') 22207 .attr('x1', this.margin.left) 22208 .attr('y1', this.yScale(0)) 22209 .attr('x2', this.innerWidth) 22210 .attr('y2', this.yScale(0)); 22211 } 22212 22213 drawBottomLine() { 22214 const x1 = this.margin.left; 22215 const y1 = this.innerHeight + this.margin.top; 22216 const x2 = this.innerWidth + this.margin.left; 22217 const y2 = this.innerHeight + this.margin.top; 22218 const darkStrokeWidth = 3; 22219 22220 this.svg 22221 .append('line') 22222 .attr('x1', x1) 22223 .attr('y1', y1) 22224 .attr('x2', x2) 22225 .attr('y2', y2) 22226 .attr('stroke', this.colors.dark) 22227 .attr('stroke-width', darkStrokeWidth); 22228 22229 this.svg 22230 .append('line') 22231 .attr('x1', x1) 22232 .attr('y1', y1 + darkStrokeWidth) 22233 .attr('x2', x2) 22234 .attr('y2', y2 + darkStrokeWidth) 22235 .attr('stroke', '#fff') 22236 .attr('stroke-width', 4); 22237 } 22238 22239 drawBars() { 22240 const getSeries = ({ className, valueIndex, color }) => { 22241 return this.svg 22242 .selectAll(`.${className}-group`) 22243 .data(this.data.values) 22244 .enter() 22245 .append('g') 22246 .attr('class', className) 22247 .append('rect') 22248 .attr('x', d => this.xScale(d.key) + this.margin.left) 22249 .attr('y', d => this.yScale(d.values[valueIndex]) + this.margin.top) 22250 .attr('width', this.xScale.bandwidth()) 22251 .attr('height', d => this.innerHeight - this.yScale(d.values[valueIndex])) 22252 .attr('fill', color); 22253 }; 22254 22255 getSeries({ 22256 className: 'total-bar', 22257 valueIndex: 0, 22258 color: this.colors.light 22259 }); 22260 22261 const percentScale = d3 22262 .scaleLinear() 22263 .domain([0, 20, 40, 60, 80, 100]) 22264 .range(['#ff6e00', '#f5aa00', '#fce400', '#aadc00', '#56bf00']); 22265 22266 getSeries({ 22267 className: 'value-bar', 22268 valueIndex: 1, 22269 color: d => 22270 this.options.customColor ? this.colors.primary : percentScale(d._percentGroup) 22271 }); 22272 } 22273 22274 drawBarMarkers = () => { 22275 const drawMarker = ({ dataIndex, className, color }) => { 22276 const y_attr = d => { 22277 return this.yScale(d.value) + this.margin.top; 22278 }; 22279 22280 const height_attr = d => { 22281 return this.BAR_DIVIDER_HEIGHT; 22282 }; 22283 22284 this.svg 22285 .selectAll(`.${className}-g`) 22286 .data(this.data.values.map(d => ({ key: d.key, value: d.values[dataIndex] }))) 22287 .enter() 22288 .append('g') 22289 .attr('class', `${className}-g`) 22290 .attr('transform', d => `translate(${this.xScale(d.key) + this.margin.left}, 0)`) 22291 .selectAll('rect') 22292 .data(d => [d]) 22293 .enter() 22294 .append('rect') 22295 .attr('class', `${className}-rect`) 22296 .attr('x', 0) 22297 .attr('y', y_attr) 22298 .attr('width', this.xScale.bandwidth()) 22299 .attr('height', height_attr) 22300 .attr('fill', color); 22301 }; 22302 22303 // divider marker 22304 const useDividerColor = (d, i) => { 22305 return d.value < this.data.values[i].values[0] + this.BAR_DIVIDER_HEIGHT; 22306 }; 22307 22308 drawMarker({ 22309 dataIndex: 1, 22310 className: 'divider-marker', 22311 color: useDividerColor ? '#ffffff' : 'transparent'
22312 }); 22313 22314 // end marker 22315 drawMarker({ 22316 dataIndex: 0, 22317 className: 'end-marker', 22318 color: this.colors.dark 22319 }); 22320 }; 22321 22322 drawOverlay() { 22323 const overlayGroups = this.svg 22324 .selectAll('.overlay-group') 22325 .data(this.data.values) 22326 .enter() 22327 .append('g') 22328 .attr('class', 'overlay-group') 22329 .attr('transform', d => `translate(${this.xScale(d.key) + this.margin.left}, 0)`); 22330 22331 overlayGroups 22332 .selectAll('.invisible-bar') 22333 .data(d => [d]) 22334 .enter() 22335 .append('rect') 22336 .attr('class', 'invisible-bar hoverable') 22337 .attr('x', 0) 22338 .attr('y', 0) 22339 .attr('width', this.xScale.bandwidth()) 22340 .attr('height', this.height + this.margin.top) 22341 .attr('fill', 'transparent') 22342 // * Debug 22343 // .attr('fill', 'red') 22344 // .attr('opacity', 0.15) 22345 .on('mouseover', this.handleMouseOver) 22346 .on('mouseout', this.handleMouseOut); 22347 } 22348 22349 handleMouseOver = (d, i) => { 22350 const data = i; 22351 22352 const $tooltip = $(this.createTooltip(data)); 22353 $(this.selector).append($tooltip); 22354 22355 // find top of bar 22356 const xBarTarget = this.xScale(i.key) + this.margin.left + this.xScale.bandwidth() / 2; 22357 const yBarTarget = this.yScale(i._max) + this.margin.top - this.BAR_DIVIDER_HEIGHT; 22358 22359 const tooltipHeight = $tooltip.height(); 22360 const tooltipWidth = $tooltip.width(); 22361 const tooltipTop = yBarTarget - tooltipHeight - 20; 22362 const tooltipLeft = xBarTarget - tooltipWidth / 2; 22363 22364 $tooltip.css({ top: tooltipTop, left: tooltipLeft }); 22365 this.svg 22366 .append('line') 22367 .attr('class', 'tooltip-dashed-line') 22368 .attr('x1', xBarTarget) 22369 .attr('y1', yBarTarget) 22370 .attr('x2', xBarTarget) 22371 .attr('y2', tooltipTop); 22372 }; 22373 22374 handleMouseOut = () => { 22375 $('.tooltip.stacked_bar_graph').remove(); 22376 this.svg.selectAll('.tooltip-dashed-line').remove(); 22377 }; 22378 22379 createTooltip(tooltipData) { 22380 const keys = this.data.keys; 22381 const label = this.options.useMonthsFormat 22382 ? KpiUtils.dateToMonthYear(tooltipData.key) 22383 : tooltipData.key; 22384 return ` 22385 <div class="tooltip stacked_bar_graph"> 22386 <div class="tooltip-content" style=""> 22387 <b>${label}</b> 22388 <br/>${keys 22389 .map((key, i) => `${key}: ${tooltipData.values[i].toLocaleString('en-US')}`) 22390 .join('<br/>')} 22391 ${ 22392 this.options.showVariance && tooltipData.values.length > 1 22393 ? `<br/>Variance: ${( 22394 tooltipData.values[1] - tooltipData.values[0] 22395 ).toLocaleString('en-US')}` 22396 : '' 22397 } 22398 </div> 22399 </div> 22400 `; 22401 } 22402 22403 unsetTooltip = () => { 22404 $('.tooltip.stacked_bar_graph').remove(); 22405 this.svg.selectAll('.tooltip-dashed-line').remove(); 22406 }; 22407 22408 destroy = () => { 22409 this.unsetTooltip(); 22410 22411 if (this.svg) { 22412 // prettier-ignore 22413 this.svg 22414 .selectAll('.invisible-bar') 22415 .on('mouseover', null) 22416 .on('mouseout', null); 22417 } 22418 22419 super.destroy(); 22420 }; 22421 22422 updateData({ data, options = {}, params = {} }) { 22423 this.params = params; 22424 this.options = options; 22425 this.data = data; 22426 this.init(); 22427 } 22428} 22429 22430 22431; 22432////pf: javascript/stats/multiline-chart.js 22433// eslint-disable-next-line no-redeclare, no-unused-vars, no-undef 22434class MultiLineGraph extends DashboardChart { 22435 constructor({ selector, data, options, params }) { 22436 if (!data?.length) { 22437 throw new Error('MultiLineGraph: no data was given.'); 22438 } 22439 if (data.every(d => d.values.every(v => v.value === 0))) { 22440 throw new Error('MultiLineGraph: all values are 0.'); 22441 } 22442 super({ selector, data }); 22443 this.options = options; 22444 this.params = params; 22445 this.timePeriod = params?.timePeriod; 22446 this.init(); 22447 } 22448 22449 margin = { top: 0, right: 10, bottom: 25, left: 45 }; 22450 graphClass = 'multiline-chart'; 22451 Y_PADDING = 10; 22452 colors = { 22453 ...KpiUtils.colors, 22454 array: [ 22455 '#00629A', 22456 '#56BF00', 22457 '#66CED6', 22458 '#F5AA00', 22459 '#f94144', 22460 '#577590', 22461 '#f3722c', 22462 '#871b4a', 22463 '#43aa8b', 22464 '#f9c74f', 22465 '#A7A5C6', 22466 '#8797b2', 22467 '#6d8a96', 22468 '#90be6d', 22469 '#66ced6', 22470 '#053c5e', 22471 '#a31621', 22472 '#b5ef8a' 22473 ] 22474 }; 22475 $tooltip = null; 22476 22477 init() { 22478 this.parseOptions(this.options); 22479 this.formatData(this.data); 22480 this.draw(); 22481 this.redrawOnResize(this.unsetTooltip); 22482 } 22483 22484 parseOptions = (options = {}) => { 22485 if (options.legend && options.legend.length > 0) { 22486 this.legendItems = options.legend; 22487 this.margin.top = 52; 22488 } 22489 }; 22490 22491 formatData = data => { 22492 this.data = data.map(dataSet => { 22493 const values = dataSet.values.map(v => { 22494 const date = new Date(v.date); 22495 return { ...v, date }; 22496 }); 22497 return { ...dataSet, values }; 22498 }); 22499 }; 22500 22501 draw = () => { 22502 this.prepareGraph(() => { 22503 this.setXDomain(); 22504 this.setYDomain(); 22505 this.setXScale(); 22506 this.setYScale(); 22507 this.setXAxis(); 22508 this.setYAxis(); 22509 this.drawLines(); 22510 this.drawPoints();
22511 this.drawOverlay(); 22512 this.prependLegend(); 22513 }, false); 22514 }; 22515 22516 prependLegend() { 22517 if (!this.legendItems) return; 22518 if (this.$legend) this.$legend.remove(); 22519 22520 this.$legend = $('<div class="metric-key"></div>'); 22521 22522 const legendKeys = this.legendItems.map(legendItem => legendItem.key); 22523 const keyColor = key => this.colors.array[legendKeys.indexOf(key)] || this.colors.secondary; 22524 22525 this.legendItems.forEach(legendItem => { 22526 const { label, formattedValue, key } = legendItem; 22527 $(` 22528 <div> 22529 <div class="label">${label}</div> 22530 <div class="value" style="color: ${keyColor(key)}">${formattedValue}</div> 22531 </div> 22532 `).appendTo(this.$legend); 22533 }); 22534 $(this.selector).prepend(this.$legend); 22535 } 22536 22537 setXDomain() { 22538 const allValues = this.data.reduce((acc, curr) => acc.concat(curr.values), []); 22539 this.xDomain = d3.extent(allValues, d => d.date); 22540 } 22541 22542 setYDomain() { 22543 const allValues = this.data.reduce((acc, curr) => acc.concat(curr.values), []); 22544 const yExtent = d3.extent(allValues, d => d.value); 22545 const yValuesPadding = (yExtent[1] - yExtent[0]) * 0.1; 22546 this.yDomain = [yExtent[0] - yValuesPadding, yExtent[1] + yValuesPadding]; 22547 } 22548 22549 setXScale() { 22550 this.xScale = d3.scaleTime().domain(this.xDomain).range([0, this.innerWidth]); 22551 } 22552 22553 setYScale() { 22554 this.yScale = d3.scaleLinear().domain(this.yDomain).range([this.innerHeight, 0]); 22555 } 22556 22557 setXAxis() { 22558 const numTicks = Math.min( 22559 KpiUtils.getResponsiveNumTicks(this.innerWidth, this.data[0].values.length), 22560 KpiUtils.getTimePeriodMaxTicksFormat( 22561 this.timePeriod, 22562 this.data[0].values.map(v => v.date) 22563 ) 22564 ); 22565 22566 this.xAxis = d3 22567 .axisBottom(this.xScale) 22568 .tickSizeOuter(0) 22569 .tickSizeInner(0) 22570 .tickPadding(0) 22571 .tickFormat(KpiUtils.getTimePeriodTickFormat(this.timePeriod)) 22572 .ticks(numTicks); 22573 22574 const xTranslate = this.margin.left; 22575 const yTranslate = this.height - this.margin.bottom - 10; 22576 22577 const xAxisWrapper = this.svg 22578 .append('g') 22579 .attr('class', 'x-axis') 22580 .attr('transform', `translate(${xTranslate}, ${yTranslate})`) 22581 .call(this.xAxis); 22582 22583 xAxisWrapper.select('.domain').remove(); 22584 } 22585 22586 setYAxis() { 22587 this.yAxis = d3 22588 .axisLeft(this.yScale) 22589 .tickSizeOuter(0) 22590 .tickSizeInner(-this.innerWidth) 22591 .tickPadding(this.Y_PADDING) 22592 .ticks(5) 22593 .tickFormat(d3.format('~s')); 22594 22595 const yAxisWrapper = this.svg 22596 .append('g') 22597 .attr('class', 'y-axis') 22598 .attr('transform', `translate(${this.margin.left}, ${this.margin.top})`) 22599 .call(this.yAxis); 22600 22601 // add the y-axis grid lines 22602 yAxisWrapper.selectAll('line').attr('class', 'grid-line'); 22603 // make bottom line solid 22604 22605 yAxisWrapper 22606 .append('line') 22607 .attr('class', 'x-axis-line-light') 22608 .attr('x1', 0) 22609 .attr('y1', this.yScale(0)) 22610 .attr('x2', this.innerWidth) 22611 .attr('y2', this.yScale(0)); 22612 } 22613 22614 drawLines() { 22615 const line = d3 22616 .line() 22617 .x(d => this.xScale(d.date)) 22618 .y(d => this.yScale(d.value)); 22619 22620 const colorScheme = this.colors.array; 22621 const colorScale = d3 22622 .scaleOrdinal() 22623 .domain(this.data.map(d => d.name)) 22624 .range(colorScheme); 22625 22626 this.svg 22627 .selectAll('.line') 22628 .data(this.data) 22629 .enter() 22630 .append('path') 22631 .attr('class', 'line') 22632 .attr('d', d => line(d.values)) 22633 .attr('transform', `translate(${this.margin.left}, ${this.margin.top})`) 22634 .attr('stroke', d => colorScale(d.name)) 22635 .attr('stroke-width', 2) 22636 .attr('fill', 'none'); 22637 } 22638 22639 drawPoints() { 22640 const colorScheme = this.colors.array; 22641 const colorScale = d3 22642 .scaleOrdinal() 22643 .domain(this.data.map(d => d.name)) 22644 .range(colorScheme); 22645 22646 const points = this.svg 22647 .selectAll('.points') 22648 .data(this.data) 22649 .enter() 22650 .append('g') 22651 .attr('class', 'points') 22652 .attr('transform', `translate(${this.margin.left}, ${this.margin.top})`); 22653 22654 points 22655 .selectAll('.point') 22656 .data(d => d.values.map(v => ({ ...v, name: d.name }))) 22657 .enter() 22658 .append('circle') 22659 .attr('class', 'point') 22660 .attr('r', 0) 22661 .attr('cx', d => this.xScale(d.date)) 22662 .attr('cy', d => this.yScale(d.value)) 22663 .style('fill', d => { 22664 const color = colorScale(d.name); 22665 return color; 22666 }); 22667 } 22668 22669 drawOverlay() { 22670 this.svg 22671 .append('rect') 22672 .attr('class', 'overlay') 22673 .attr('x', this.margin.left) 22674 .attr('y', this.margin.top) 22675 .attr('width', this.innerWidth) 22676 .attr('height', this.innerHeight) 22677 .attr('fill', 'transparent') 22678 .on('mouseover', this.handleMouseOver) 22679 .on('mouseout', this.handleMouseOut) 22680 .on('mousemove', this.handleMouseMove); 22681 } 22682 22683 handleMouseOver = () => { 22684 if (this.$tooltip) return; 22685 this.$tooltip = $(this.createTooltip()).appendTo(this.selector); 22686 }; 22687 22688 handleMouseOut = () => { 22689 if (this.$tooltip) { 22690 this.$tooltip.remove(); 22691 this.$tooltip = null; 22692 } 22693 KpiUtils.placeSvgCircle.off(this.svg); 22694 $(this.selector).find('.tooltip-dashed-line').remove(); 22695 }; 22696 22697 /** 22698 * This function is called when the mouse moves over the chart. 22699 * It finds the closest data points to the mouse, draws a dashed line, highlights the points, and shows the tooltip. 22700 * @param {*} event - The mousemove event - will be passed to d3.pointer 22701 */ 22702 handleMouseMove = event => { 22703 KpiUtils.placeSvgCircle.off(this.svg); 22704 $(this.selector).find('.tooltip-dashed-line').remove(); 22705 22706 const [x, y] = d3.pointer(event); 22707 const bisectDate = d3.bisector(d => d.date).left; 22708 const xCoordinate = this.xScale.invert(x - this.margin.left); // Adjust for left margin] 22709 22710 // Find the index of the data point to the left of the mouse in each series 22711 const seriesIndexLeft = this.data.map(series => { 22712 const index = bisectDate(series.values, xCoordinate); 22713 return index > 0 ? index - 1 : 0; 22714 }); 22715 22716 // Find the index of the data point to the right of the mouse in each series 22717 const seriesIndexRight = this.data.map(series => { 22718 const index = bisectDate(series.values, xCoordinate); 22719 return index < series.values.length - 1 ? index : series.values.length - 1; 22720 }); 22721 22722 // Get the x and y values of the left and right data points, adjusted for margins 22723 const points = this.data.map((series, i) => { 22724 const indexLeft = seriesIndexLeft[i]; 22725 const indexRight = seriesIndexRight[i]; 22726 const dLeft = series.values[indexLeft];
22727 const dRight = series.values[indexRight]; 22728 const distLeft = Math.abs(this.xScale(dLeft.date) + this.margin.left - x); 22729 const distRight = Math.abs(this.xScale(dRight.date) + this.margin.left - x); 22730 const d = distLeft < distRight ? dLeft : dRight; 22731 return { 22732 date: d.date, 22733 x: this.xScale(d.date) + this.margin.left, 22734 y: this.yScale(d.value) + this.margin.top, 22735 seriesIndex: i, 22736 dataIndex: distLeft < distRight ? indexLeft : indexRight 22737 }; 22738 }); 22739 22740 // point in points which y value is closest to the mouse 22741 const closestPoint = points.reduce( 22742 (acc, point) => { 22743 const dist = Math.abs(point.y - y); 22744 return dist < acc.dist ? { ...point, dist } : acc; 22745 }, 22746 { dist: Infinity } 22747 ); 22748 22749 const toolTipData = points.map(point => { 22750 const { seriesIndex, dataIndex } = point; 22751 const name = this.data[seriesIndex].name; 22752 const value = this.data[seriesIndex].values[dataIndex].value; 22753 return { name, value }; 22754 }); 22755 22756 if (this.$tooltip) { 22757 const label = KpiUtils.dateToShortMonthDayYear(points[0].date); 22758 const tooltipHtml = ` 22759 <div class="tooltip-content"> 22760 <b>${label}</b> 22761 ${toolTipData 22762 .map( 22763 (d, i) => 22764 `<div class='no-wrap'> 22765 <span class='tooltip-color' style='background-color: ${this.colors.array[i]}'></span> 22766 ${d.name}: ${d.value} 22767 </div>` 22768 ) 22769 .join('')} 22770 </div> 22771 `; 22772 this.$tooltip.html(tooltipHtml); 22773 22774 const dotRadius = 4; 22775 22776 const getTop = () => { 22777 const dynamic = closestPoint.y - this.$tooltip.height() - dotRadius; 22778 const max = 0; // y value of top of chart 22779 const min = this.innerHeight; 22780 return Math.min(Math.max(dynamic, max), min); 22781 }; 22782 22783 const getLeft = () => { 22784 const dynamic = closestPoint.x - this.$tooltip.width() / 2; 22785 const max = 0; // x value of left of chart 22786 const min = this.innerWidth - this.$tooltip.width() / 2; 22787 return Math.min(Math.max(dynamic, max), min); 22788 }; 22789 22790 const dashedLineY2 = this.innerHeight + this.margin.bottom - this.Y_PADDING - dotRadius; 22791 22792 this.svg 22793 .append('line') 22794 .attr('class', 'tooltip-dashed-line') 22795 .attr('x1', closestPoint.x) 22796 .attr('y1', getTop()) 22797 .attr('x2', closestPoint.x) 22798 .attr('y2', dashedLineY2); 22799 22800 // Draw circles on each data point 22801 points.forEach((point, i) => { 22802 KpiUtils.placeSvgCircle.on(this.svg, point.x, point.y, this.colors.array[i], dotRadius); 22803 }); 22804 22805 this.$tooltip.css({ 22806 left: getLeft(), 22807 top: getTop() 22808 }); 22809 } 22810 }; 22811 22812 createTooltip() { 22813 return '<div class="tooltip multiline-chart__tooltip"></div'; 22814 } 22815 22816 unsetTooltip = () => { 22817 this.$tooltip && this.$tooltip.remove(); 22818 this.$tooltip = null; 22819 }; 22820 22821 destroy = () => { 22822 $(this.selector).find('.multiline-chart__tooltip').remove(); 22823 $(this.selector).find('.tooltip-dashed-line').remove(); 22824 this.unsetTooltip(); 22825 22826 if (this.svg) { 22827 this.svg 22828 .selectAll('.overlay') 22829 .on('mousemove', null) 22830 .on('mouseout', null) 22831 .on('mouseover', null); 22832 } 22833 super.destroy(); 22834 }; 22835 22836 updateData = ({ data, options, params }) => { 22837 if (!data?.length) { 22838 throw new Error('MultiLineGraph: no data was given.'); 22839 } 22840 this.timePeriod = params?.timePeriod; 22841 this.options = options; 22842 this.data = data; 22843 this.init(); 22844 }; 22845} 22846 22847 22848; 22849////pf: javascript/stats/economic-units.js 22850// eslint-disable-next-line no-redeclare 22851class EconomicUnit { 22852 constructor({ 22853 selector, 22854 label, 22855 formattedValue, 22856 formattedValueType, 22857 subLabel, 22858 trendTimePeriodName, 22859 trendValue, 22860 trendValueType, 22861 includeTrend = false 22862 }) { 22863 if (!formattedValue) { 22864 throw new Error('EconomicUnit: missing fields.'); 22865 } 22866 this.selector = selector; 22867 this.label = label; 22868 this.formattedValue = formattedValue; 22869 this.formattedValueType = formattedValueType || ''; // positive, negative, neutral, null 22870 this.subLabel = subLabel; 22871 this.trendTimePeriodName = trendTimePeriodName || 'previous'; 22872 this.trendValue = trendValue; 22873 this.trendValueType = trendValueType || ''; // positive, negative, neutral, null 22874 this.includeTrend = includeTrend; 22875 22876 this.init(); 22877 } 22878 22879 init() { 22880 const $el = $('<div class="economic-unit"></div>'); 22881 22882 $el.append(`<div class="economic-unit__label">${this.label}</div>`); 22883 22884 $el.append( 22885 `<div class="economic-unit__value ${this.formattedValueType}">${this.formattedValue}</div>` 22886 ); 22887 22888 if (this.subLabel) {
22889 $el.append(`<div class="economic-unit__subLabel">${this.subLabel}</div>`); 22890 } 22891 22892 if (this.includeTrend) { 22893 let trendIcon = ''; 22894 if (this.trendValueType === 'positive') { 22895 trendIcon = '<i class="fas fa-arrow-up"></i>'; 22896 } else if (this.trendValueType === 'negative') { 22897 trendIcon = '<i class="fas fa-arrow-down"></i>'; 22898 } else if (this.trendValueType === 'neutral') { 22899 trendIcon = '<i class="fas fa-arrow-right"></i>'; 22900 } 22901 22902 $el.append(` 22903 <div class="economic-unit__trend"> 22904 <span class="trend-value ${this.trendValueType}"> 22905 ${trendIcon} ${this.trendValue || 0} 22906 </span> 22907 vs ${this.trendTimePeriodName} 22908 </div> 22909 `); 22910 } 22911 22912 if (this.selector) { 22913 $(this.selector).append($el); 22914 } 22915 22916 return $el; 22917 } 22918} 22919 22920EconomicUnit.createGroup = function ({ selector, data }) { 22921 // if data is not an array throw an error 22922 if (!data || !data.length || !Array.isArray(data)) { 22923 KpiUtils._tileElementAlert(selector).show(); 22924 throw new Error(`EconomicUnit.createGroup: Selector ${selector} has no data.`); 22925 } 22926 $(selector).empty(); 22927 $(selector).addClass('economic-unit-group').css({ height: '100%' }); 22928 data.forEach(unit => { 22929 new EconomicUnit({ ...unit, selector }); 22930 }); 22931}; 22932 22933 22934; 22935////pf: javascript/stats/ar-bands.js 22936// eslint-disable-next-line no-redeclare 22937const AgingSummaryBands = {}; 22938 22939AgingSummaryBands.createDataBands = ({ selector, data, formattedTotal }) => { 22940 $(selector).empty(); 22941 const $el = $('<div class="bands-stats"></div>'); 22942
22943 const $bandsContainer = $('<div class="bands-container"></div>'); 22944 const $bandGroup = $('<div class="band-group"></div>'); 22945 const $band = $('<div class="band"></div>'); 22946 const $bandLabel = $('<div class="band-label"></div>'); 22947 const $bandStat = $('<div class="band-value"></div>'); 22948 22949 data.forEach(d => { if (d.value == null) d.value = 0; }); 22950 const sorted = [...data].sort((a, b) => b.value - a.value); 22951 22952 const divisor = sorted[0].value; 22953 22954 const color = KpiUtils.colors; 22955 const colorScale = [ 22956 color.light, 22957 color.keyLightGreen, 22958 color.keyYellow, 22959 color.keyOrange, 22960 color.keyRedOrange 22961 ]; 22962 22963 data.forEach((band, index) => { 22964 const $bandGroupClone = $bandGroup.clone(); 22965 const $bandClone = $band.clone(); 22966 const $bandLabelClone = $bandLabel.clone(); 22967 const $bandStatClone = $bandStat.clone(); 22968 22969 $bandClone.css({ 22970 'flex-grow': band.value / divisor, 22971 'flex-shrink': 1, 22972 'flex-basis': '0%', 22973 'background-color': colorScale[index] 22974 }); 22975 $bandLabelClone.text(band.name); 22976 $bandStatClone.text(band.stat); 22977 22978 $bandGroupClone.append($bandStatClone); 22979 $bandGroupClone.append($bandClone); 22980 $bandGroupClone.append($bandLabelClone); 22981 22982 $bandsContainer.append($bandGroupClone); 22983 }); 22984 22985 $el.append($bandsContainer); 22986 22987 if (formattedTotal) { 22988 $el.append(` 22989 <div class="total-label"> 22990 <div> 22991 <p class="total-label__label">Total</p> 22992 <b class="total-label__value">${formattedTotal}</b> 22993 </div> 22994 </div> 22995 `); 22996 } 22997 22998 $(selector).append($el).addClass('bands-stat-outer'); 22999}; 23000 23001 23002; 23003////pf: javascript/stats/ar-table.js 23004// eslint-disable-next-line no-redeclare, no-unused-vars 23005class ArProgramTable { 23006 constructor({ selector, data, params = {} }) { 23007 if (!data?.length) { 23008 throw new Error('ArProgramTable: data is required.'); 23009 } 23010 this.selector = selector; 23011 this.data = data; 23012 this.params = params; 23013 23014 this.tooltip = 'Total Outstanding A/R by program'; 23015 this.title = 'Accounts Receivable'; 23016 23017 this.sortByHigh = true; 23018 this.$ArProgramTable = $(selector); 23019 23020 this.init(); 23021 } 23022 23023 init = () => { 23024 this.$ArProgramTable.empty(); 23025 this.render(); 23026 }; 23027 23028 $header = null; 23029 $sortingControl = null; 23030 $table = null; 23031 23032 renderHeader = ({ tooltip, title }) => { 23033 if (!this.$header) { 23034 this.$header = $(` 23035 <div class="subheader-group"> 23036 <a href="#" data-tooltip></a> 23037 <h3>${title}</h3> 23038 </div> 23039 `); 23040 KpiTile.setTooltipSimply(this.$header.find('[data-tooltip]'), tooltip); 23041 23042 this.$ArProgramTable.append(this.$header); 23043 } 23044 }; 23045 23046 renderSortingControl = () => { 23047 if (!this.$sortingControl) { 23048 this.$sortingControl = $(` 23049 <div class="kpi-tile__sorting"> 23050 <a href="#" data-next=""> 23051 <i class="fas fa-arrow-up"></i> 23052 High 23053 </a> 23054 <a href="#" data-next="showTopResults" style="display: none;"> 23055 <i class="fas fa-arrow-down"></i> 23056 Low 23057 </a> 23058 </div> 23059 `); 23060 this.handleSortClick(); 23061 23062 this.$header.append(this.$sortingControl); 23063 } 23064 }; 23065 23066 updateSortingControl = (sortByHigh = this.sortByHigh) => { 23067 const $control = this.$sortingControl.find('a'); 23068 if (sortByHigh) { 23069 $control.hide().eq(0).show(); 23070 } else { 23071 $control.hide().eq(1).show(); 23072 } 23073 }; 23074 23075 enableControl = ($anchor, enable = true) => { 23076 const pointerEvents = enable ? 'auto' : 'none'; 23077 const opacity = enable ? '1' : '0.5'; 23078 $anchor.css('pointer-events', pointerEvents); 23079 this.$sortingControl.css({ 'pointer-events': pointerEvents, opacity }); 23080 }; 23081 23082 handleSortClick = () => { 23083 this.$sortingControl.on('click', 'a', async e => { 23084 e.preventDefault(); 23085 23086 const $anchor = $(e.currentTarget); 23087 this.enableControl($anchor, false); 23088 23089 const showTopResults = $anchor.data('next') === 'showTopResults'; 23090 this.sortByHigh = !this.sortByHigh; 23091 this._callSorting(); 23092 23093 this.updateSortingControl(); 23094 this.enableControl($anchor, true); 23095 }); 23096 }; 23097 23098 renderTable() { 23099 if (this.$table) { 23100 this.$table.remove(); 23101 } 23102 this.$table = $(`<table class="kpi-program-table"></table>`); 23103 const $tbody = $('<tbody></tbody>'); 23104 23105 this.data.forEach(row => { 23106 const $tr = $( 23107 `<tr> 23108 <td><img class="ar-program-img" src="${row.img}" alt="Program"></td> 23109 <td class="program-ar-name"><a href="${row.link}">${row.name}</a></td> 23110 <td class="program-ar-value">${row.ar}</td> 23111 </tr>` 23112 ); 23113 $tbody.append($tr); 23114 }); 23115 this.$table.append($tbody); 23116 23117 this.$ArProgramTable.append(this.$table); 23118 } 23119 23120 render() { 23121 this.renderHeader({ tooltip: this.tooltip, title: this.title }); 23122 this.renderSortingControl(); 23123 this.renderTable(); 23124 } 23125 23126 destroy() { 23127 this.$ArProgramTable.empty(); 23128 this.$ArProgramTable = null; 23129 this.$header = null; 23130 this.$sortingControl = null; 23131 this.$table = null; 23132 } 23133 23134 updateData({ data, params = {} }) { 23135 this.params = params; 23136 this.data = data; 23137 this.render(); 23138 } 23139 23140 _callSorting = async () => { 23141 const element = getElementBySelector(this.selector); 23142 element.queryParams = { ...element.queryParams, showTopResults: this.sortByHigh }; 23143 KpiUtils.rerenderTileElement({ ...element }); 23144 }; 23145} 23146 23147 23148; 23149////pf: javascript/stats/revenue-vs-expense.graph.js 23150// eslint-disable-next-line no-redeclare, no-unused-vars, no-undef 23151class RevenueVsExpenseGraph extends DashboardChart { 23152 constructor({ selector, data }) { 23153 try { 23154 super({ selector, data }); 23155 if (!data || !data.length || !Array.isArray(data)) { 23156 throw new Error('RevenueVsExpenseGraph: data is empty.'); 23157 } 23158 if (data.length < 2) { 23159 throw new Error('RevenueVsExpenseGraph: data has too few items :: ', data.length); 23160 } 23161 this.init(data); 23162 } catch (error) { 23163 // eslint-disable-next-line no-console 23164 console.error(error); 23165 throw error; 23166 } 23167 } 23168 23169 init(data) { 23170 this.data = data.map(this.formatData); 23171 this.margin = { top: 35, right: 20, bottom: 90, left: 50 }; 23172 this.graphClass = 'revenue-vs-expense-graph'; 23173 this.viewboxYPadding = 20; 23174 this.xScale = d3.scaleBand(); 23175 this.yScale = d3.scaleLinear(); 23176 super.init(); 23177 } 23178 23179 /** 23180 * Reformats null values to empty strings or 0 23181 * @param {*} data - original data 23182 * @param {*} index - index in the data array which is used as a key 23183 * @returns {object} - formatted data 23184 */ 23185 formatData = (data, index) => { 23186 data.program = data.program || ''; 23187 data.revenue = data.revenue || 0; 23188 data.revenueBudget = data.revenueBudget || 0; 23189 data.expense = data.expense || 0; 23190 data.expenseBudget = data.expenseBudget || 0; 23191 data.profitMargin = data.profitMargin || 0; 23192 return { ...data, index }; 23193 }; 23194 23195 bar_width = () => this.xScale.bandwidth(); 23196 23197 bar_x_attr = (d, i) => this.xScale(this.xDomain[i]) + this.margin.left; 23198 23199 bar_x_attr_label = (d, i) => 23200 this.xScale(this.xDomain[i]) + this.margin.left + this.bar_width() / 2; 23201 23202 bar_y_attr = d => this.yScale(d) + this.margin.top; 23203 23204 bar_y_attr_inverted = () => this.yScale(0) + this.margin.top; 23205 23206 k_value_format = d => { 23207 const formatter = new Intl.NumberFormat('en-US', { 23208 maximumSignificantDigits: 3, 23209 minimumFractionDigits: 0, 23210 maximumFractionDigits: 1, 23211 useGrouping: false, 23212 notation: 'compact', 23213 compactDisplay: 'short' 23214 }); 23215 return formatter.format(Math.abs(d)); 23216 }; 23217 23218 draw_y = d => { 23219 const measurement = this.yScale(0) - this.yScale(d); 23220 if (measurement < 0) { 23221 // eslint-disable-next-line no-console 23222 console.warn('draw_y: Negative measurement', d, measurement); 23223 return 0; 23224 } 23225 return measurement; 23226 }; 23227 23228 rem_size = parseFloat(getComputedStyle(document.documentElement).fontSize); 23229 23230 draw() { 23231 this.prepareGraph(() => { 23232 this.setXDomain(); 23233 this.setYDomain(); 23234 this.setXScale(); 23235 this.setYScale(); 23236 this.setYAxis(); 23237 this.setXAxisForBars(10, false); 23238 this.drawYAxisLine(); 23239 this.drawXAxisLine(); 23240 this.drawRevenueBudgetBars(); 23241 this.drawRevenueBars(); 23242 this.drawRevenueBudgetLimits(); 23243 this.drawRevenueBarLabels(); 23244 this.drawExpenseBudgetBars(); 23245 this.drawExpenseBars(); 23246 this.drawExpenseBudgetLimits(); 23247 this.drawExpenseBarLabels(); 23248 this.drawOverlay(); 23249 23250 // Show graph/table button on render. Not the best place for this, but it works. 23251 $('#revenue_vs_expense_toggle').css('visibility', 'visible'); 23252 }, true); 23253 } 23254 23255 setXDomain() { 23256 this.xDomain = this.data.map(d => d.program); 23257 } 23258 23259 setYDomain() { 23260 const yValues = this.data.reduce((acc, cur) => { 23261 return acc.concat([cur.revenue, cur.revenueBudget, cur.expense, cur.expenseBudget]); 23262 }, []); 23263 23264 this.yDomain = d3.extent(yValues); 23265 23266 if (this.yDomain[0] > 0) { 23267 this.yDomain[0] = 0; 23268 } else if (this.yDomain[1] < 0) { 23269 this.yDomain[1] = 0; 23270 } 23271 } 23272 23273 setXScale() { 23274 this.xScale.domain(this.xDomain).range([0, this.innerWidth]).padding(0.2); 23275 } 23276 23277 setYScale() { 23278 this.yScale.domain(this.yDomain).range([this.innerHeight, 0]); 23279 } 23280 23281 setYAxis() { 23282 this.yAxis = d3 23283 .axisLeft(this.yScale) 23284 .tickSizeOuter(0) 23285 .tickSizeInner(-this.innerWidth) 23286 .tickPadding(10)
23287 .tickFormat(KpiUtils.graphTickFormatKM) 23288 .ticks(6); 23289 23290 this.yAxisWrapper = this.svg 23291 .append('g') 23292 .attr('class', 'y-axis-wrapper') 23293 .attr('transform', `translate(${this.margin.left}, ${this.margin.top})`) 23294 .call(this.yAxis); 23295 23296 this.yAxisWrapper.select('path.domain').remove(); 23297 23298 this.yAxisWrapper 23299 .selectAll('text') 23300 .attr('fill', this.colors.dark) 23301 .attr('font-size', '14px') 23302 .attr('letter-spacing', '0.15px') 23303 .attr('font-weight', 'bold') 23304 .attr('text-anchor', 'end'); 23305 23306 this.yAxisWrapper.select('.domain').attr('transform', `translate(0, ${this.yScale(0)})`); 23307 23308 this.yAxisWrapper.selectAll('line').attr('class', 'grid-line'); 23309 } 23310 23311 drawXAxisLine() { 23312 this.yAxisWrapper 23313 .append('line') 23314 .attr('class', 'x-axis-line') 23315 .attr('x1', 0) 23316 .attr('y1', this.yScale(0)) 23317 .attr('x2', this.innerWidth) 23318 .attr('y2', this.yScale(0)) 23319 .attr('stroke', 'black') 23320 .attr('stroke-width', 2); 23321 } 23322 23323 drawYAxisLine() { 23324 const _bottom = this.innerHeight + this.margin.top; 23325 const _top = this.margin.top; 23326 const _left = this.margin.left; 23327 const origin = this.yScale(0) + this.margin.top; 23328 23329 this.svg 23330 .append('line') 23331 .attr('class', 'y-axis-line negative') 23332 .attr('x1', _left) 23333 .attr('x2', _left) 23334 .attr('y1', origin) 23335 .attr('y2', _bottom) 23336 .attr('stroke', this.colors.negative) 23337 .attr('stroke-width', 2); 23338 23339 this.svg 23340 .append('line') 23341 .attr('class', 'y-axis-line positive') 23342 .attr('x1', _left) 23343 .attr('x2', _left) 23344 .attr('y1', _top) 23345 .attr('y2', origin) 23346 .attr('stroke', this.colors.positive) 23347 .attr('stroke-width', 2); 23348 } 23349 23350 drawRevenueBars() { 23351 this.svg 23352 .selectAll('.revenue-bar') 23353 .data(this.data.map(d => d.revenue)) 23354 .enter() 23355 .append('rect') 23356 .attr('class', 'revenue-bar') 23357 .attr('x', this.bar_x_attr) 23358 .attr('y', this.bar_y_attr) 23359 .attr('width', this.bar_width) 23360 .attr('height', this.draw_y) 23361 .attr('fill', this.colors.positive); 23362 } 23363 23364 drawRevenueBarLabels() { 23365 const labelYPlacement = this.yScale(0) + 2 * this.rem_size; 23366 23367 const fillFn = d => { 23368 const labelHeight = labelYPlacement; 23369 const barHeight = this.bar_y_attr(d); 23370 const diff = labelHeight - barHeight; 23371 23372 return diff > this.rem_size ? 'white' : 'transparent'; 23373 }; 23374 23375 this.svg 23376 .selectAll('.revenue-bar-label') 23377 .data(this.data.map(d => d.revenue)) 23378 .enter() 23379 .append('text') 23380 .attr('class', 'revenue-bar-label') 23381 .style('font-weight', 'bold') 23382 .attr('x', this.bar_x_attr_label) 23383 .attr('y', this.yScale(0) + 2 * this.rem_size) 23384 .attr('text-anchor', 'middle') 23385 .attr('fill', fillFn) 23386 .text(this.k_value_format); 23387 } 23388 23389 drawRevenueBudgetBars() { 23390 this.svg 23391 .selectAll('.revenue-budget-bar') 23392 .data(this.data.map(d => d.revenueBudget)) 23393 .enter() 23394 .append('rect') 23395 .attr('class', 'revenue-budget-bar') 23396 .attr('x', this.bar_x_attr) 23397 .attr('y', this.bar_y_attr) 23398 .attr('width', this.bar_width) 23399 .attr('height', this.draw_y) 23400 .attr('fill', this.colors.light); 23401 } 23402 23403 drawRevenueBudgetLimits() { 23404 // const xAxisLine = this.yScale(0) + this.margin.top; 23405 this.svg 23406 .selectAll('.revenue-budget-bar-top') 23407 .data(this.data.map(d => d.revenueBudget)) 23408 .enter() 23409 .append('rect') 23410 .attr('class', 'revenue-budget-bar-top') 23411 .attr('x', this.bar_x_attr) 23412 .attr('y', d => this.yScale(d) + this.margin.top) 23413 .attr('width', this.bar_width) 23414 .attr('height', d => (d === 0 ? 0 : 3)) 23415 .attr('fill', this.colors.dark); 23416 } 23417 23418 drawExpenseBars() { 23419 this.svg 23420 .selectAll('.expense-bar') 23421 .data(this.data.map(d => Math.abs(d.expense))) 23422 .enter() 23423 .append('rect') 23424 .attr('class', 'expense-bar') 23425 .attr('x', this.bar_x_attr) 23426 .attr('y', this.bar_y_attr_inverted) 23427 .attr('width', this.bar_width) 23428 .attr('height', this.draw_y) 23429 .attr('fill', this.colors.negative); 23430 } 23431 23432 drawExpenseBarLabels() { 23433 const getY = () => this.yScale(0) + 3.5 * this.rem_size + 2; 23434 const fillFn = d => { 23435 const barHeight = this.yScale(0) - this.yScale(d); 23436 return barHeight > 2 * this.rem_size ? 'white' : 'transparent'; 23437 }; 23438 this.svg 23439 .selectAll('.expense-bar-label') 23440 .data(this.data.map(d => Math.abs(d.expense))) 23441 .enter() 23442 .append('text') 23443 .attr('class', 'expense-bar-label') 23444 .style('font-weight', 'bold') 23445 .attr('x', this.bar_x_attr_label) 23446 .attr('y', getY) 23447 .attr('text-anchor', 'middle') 23448 .attr('fill', fillFn) 23449 .text(this.k_value_format); 23450 } 23451 23452 drawExpenseBudgetBars() { 23453 this.svg 23454 .selectAll('.expense-budget-bar') 23455 .data(this.data.map(d => Math.abs(d.expenseBudget))) 23456 .enter() 23457 .append('rect') 23458 .attr('class', 'expense-budget-bar') 23459 .attr('x', this.bar_x_attr) 23460 .attr('y', this.bar_y_attr_inverted) 23461 .attr('width', this.bar_width) 23462 .attr('height', this.draw_y) 23463 .attr('fill', this.colors.light); 23464 } 23465 23466 drawExpenseBudgetLimits() { 23467 this.svg 23468 .selectAll('.expense-budget-bar-top') 23469 .data(this.data.map(d => Math.abs(d.expenseBudget))) 23470 .enter() 23471 .append('rect') 23472 .attr('class', 'expense-budget-bar-top') 23473 .attr('x', this.bar_x_attr) 23474 .attr('y', d => 2 * this.yScale(0) - this.yScale(d) + this.margin.top) 23475 .attr('width', this.bar_width) 23476 .attr('height', d => (d === 0 ? 0 : 3)) 23477 .attr('fill', this.colors.dark); 23478 } 23479 23480 drawOverlay() { 23481 this.svg 23482 .selectAll('.invisible-bar') 23483 .data(this.data.map(d => d.index)) 23484 .enter() 23485 .append('rect') 23486 .attr('class', 'invisible-bar hoverable')
23487 .attr('x', (d, i) => this.xScale(this.xDomain[i]) + this.margin.left) 23488 .attr('y', 0) 23489 .attr('width', this.xScale.bandwidth()) 23490 .attr('height', this.height + this.margin.top) 23491 .attr('transform', `translate(0, ${-this.margin.top})`) 23492 .attr('fill', 'transparent') 23493 // * Debug 23494 // .attr('fill', 'red') 23495 // .attr('opacity', 0.1) 23496 .on('mouseover', this.handleMouseOver) 23497 .on('mouseout', this.handleMouseOut); 23498 } 23499 23500 handleMouseOver = (d, i) => { 23501 const data = this.data.filter(d => d.index === i)[0]; 23502 const $tooltip = $(this.createTooltip(data)); 23503 $(this.selector).append($tooltip); 23504 23505 // find top of bar 23506 const xBarTarget = 23507 this.xScale(this.xDomain[i]) + this.margin.left + this.xScale.bandwidth() / 2; 23508 const yBarTarget = this.yScale(Math.max(data.revenue, data.revenueBudget)) + this.margin.top; 23509 23510 let tooltipHeight = $tooltip.height(); 23511 let tooltipWidth = $tooltip.width(); 23512 let tooltipTop = yBarTarget - tooltipHeight - 20; 23513 let tooltipLeft = xBarTarget - tooltipWidth / 2; 23514 23515 const padForEdges = 7; 23516 23517 // if tooltip is too far to the right, move it left 23518 if (tooltipLeft + tooltipWidth > this.width) { 23519 tooltipLeft = this.width - tooltipWidth - padForEdges; 23520 } 23521 // if tooltip is too far to the left, move it right 23522 if (tooltipLeft < 0) { 23523 tooltipLeft = 0 + padForEdges; 23524 } 23525 // if tooltip is too far up, move it down by so the top of the tooltip is at the highest point of the graph container 23526 if (tooltipTop < 0) { 23527 tooltipTop = 0 + padForEdges; 23528 } 23529 // if tooltip is too far down, move it up 23530 if (tooltipTop + tooltipHeight > this.height) { 23531 tooltipTop = this.height - tooltipHeight - padForEdges; 23532 } 23533 23534 $tooltip.css({ left: tooltipLeft, top: tooltipTop }); 23535 this.svg 23536 .append('line') 23537 .attr('class', 'tooltip-dashed-line') 23538 .attr('x1', xBarTarget) 23539 .attr('y1', yBarTarget) 23540 .attr('x2', xBarTarget) 23541 .attr('y2', tooltipTop); 23542 }; 23543 23544 handleMouseOut = () => { 23545 $('.tooltip.revenue_vs_expense').remove(); 23546 this.svg.selectAll('.tooltip-dashed-line').remove(); 23547 }; 23548 23549 createTooltip(data) { 23550 const revenue = '$' + this.k_value_format(data.revenue); 23551 const revenueBudget = '$' + this.k_value_format(data.revenueBudget); 23552 const expense = '$' + this.k_value_format(data.expense); 23553 const expenseBudget = '$' + this.k_value_format(data.expenseBudget); 23554 const profitMargin = `${data.profitMargin}%`; 23555 23556 return ` 23557 <div class="tooltip revenue_vs_expense"> 23558 <div class="tooltip-content"> 23559 <b>${data.program}</b> 23560 <br/> 23561 Profit Margin: ${profitMargin} 23562 <br/> 23563 Revenue: ${revenue} | Revenue Budget: ${revenueBudget} 23564 <br/> 23565 Expense: ${expense} | Expense Budget: ${expenseBudget} 23566 </div> 23567 </div> 23568 `; 23569 } 23570 23571 unsetTooltip = () => { 23572 $('.tooltip.revenue_vs_expense').remove(); 23573 this.svg.selectAll('.tooltip-dashed-line').remove(); 23574 }; 23575 23576 destroy = () => { 23577 this.unsetTooltip(); 23578 23579 if (this.svg) { 23580 // prettier-ignore 23581 this.svg 23582 .selectAll('.invisible-bar') 23583 .on('mouseover', null) 23584 .on('mouseout', null); 23585 } 23586 23587 super.destroy(); 23588 }; 23589 23590 updateData(props) { 23591 try { 23592 this.init(props.data); 23593 } catch (error) { 23594 // eslint-disable-next-line no-console 23595 console.error(error); 23596 throw new Error('Error initializing data'); 23597 } 23598 } 23599} 23600 23601 23602; 23603////pf: javascript/stats/waterfall.js 23604// eslint-disable-next-line no-redeclare, no-unused-vars, no-undef 23605class ShortfallWaterfallGraph extends DashboardChart { 23606 constructor({ selector, data }) { 23607 try { 23608 super({ selector, data }); 23609 if (!data?.length) { 23610 throw new Error('ShortfallWaterfallGraph: data is required.'); 23611 } 23612 this.init(); 23613 } catch (error) { 23614 // eslint-disable-next-line no-console 23615 console.error(error); 23616 throw error; 23617 } 23618 } 23619 23620 graphClass = 'waterfall-graph'; 23621 viewboxYPadding = 20; 23622 23623 init() { 23624 // initialization happens here 23625 this.margin = { top: 25, right: 20, bottom: 100, left: 50 }; 23626 this.xScale = d3.scaleBand(); 23627 this.yScale = d3.scaleLinear(); 23628 super.init(); 23629 } 23630 23631 draw() { 23632 this._data = []; 23633 this.prepareGraph(() => { 23634 this.setValues();
23635 this.setXAxisForBars(18, true); 23636 this.setYAxis(); 23637 this.drawBars(); 23638 this.drawBarLabels(); 23639 }, true); 23640 } 23641 23642 setValues() { 23643 const programNames = this.data.map(d => d.program); 23644 const xDomain = programNames.concat(['Subtotal']); 23645 23646 let subtotal = 0; 23647 const values = this.data.map(d => { 23648 subtotal += d.amount; 23649 return { y1: subtotal - d.amount, y2: subtotal }; 23650 }); 23651 23652 const yValues = values.concat({ y1: 0, y2: subtotal }); 23653 const yDomain = [0, subtotal]; 23654 23655 const subtotalData = { program: 'Subtotal', amount: subtotal }; 23656 23657 this._data = this.data.concat(subtotalData).map((d, i) => ({ 23658 ...d, 23659 y1: yValues[i].y1, 23660 y2: yValues[i].y2 23661 })); 23662 23663 this.xScale.domain(xDomain).range([0, this.innerWidth]).padding(0.2); 23664 this.yScale.domain(yDomain).range([this.innerHeight, 0]); 23665 } 23666 23667 setYAxis() { 23668 this.yAxis = d3 23669 .axisLeft(this.yScale) 23670 .tickSizeOuter(0) 23671 .tickSizeInner(-this.innerWidth) 23672 .tickPadding(10) 23673 .tickFormat(KpiUtils.graphTickFormatKM) 23674 .ticks(5); 23675 23676 const yAxisWrapper = this.svg 23677 .append('g') 23678 .attr('transform', `translate(${this.margin.left}, ${this.margin.top})`) 23679 .call(this.yAxis); 23680 23681 yAxisWrapper.select('path.domain').remove(); 23682 23683 yAxisWrapper 23684 .selectAll('text') 23685 .attr('fill', this.colors.dark) 23686 .attr('font-size', '14px') 23687 .attr('letter-spacing', '0.15px') 23688 .attr('font-weight', 'bold') 23689 .attr('text-anchor', 'end'); 23690 23691 yAxisWrapper.selectAll('line').attr('class', 'grid-line'); 23692 23693 yAxisWrapper 23694 .append('line') 23695 .attr('class', 'x-axis-line') 23696 .attr('x1', 0) 23697 .attr('y1', this.yScale(0)) 23698 .attr('x2', this.innerWidth) 23699 .attr('y2', this.yScale(0)) 23700 .attr('stroke', 'black') 23701 .attr('stroke-width', 2); 23702 } 23703 23704 drawBars() { 23705 const { primary, secondary } = this.colors; 23706 this.svg 23707 .selectAll('.waterfall-bar') 23708 .data(this._data) 23709 .enter() 23710 .append('rect') 23711 .attr('class', 'waterfall-bar') 23712 .attr('x', d => this.xScale(d.program) + this.margin.left) 23713 .attr('y', d => this.yScale(Math.max(d.y1, d.y2)) + this.margin.top) 23714 .attr('width', this.xScale.bandwidth()) 23715 .attr('height', d => Math.abs(this.yScale(d.y1) - this.yScale(d.y2))) 23716 .attr('fill', (d, i) => (i !== this._data.length - 1 ? primary : secondary)); 23717 } 23718 23719 drawBarLabels() { 23720 const { primary, secondary } = this.colors; 23721 const currencyFormatter = new Intl.NumberFormat('en-US', { 23722 style: 'currency', 23723 currency: 'USD', 23724 minimumFractionDigits: 0, 23725 maximumFractionDigits: 1, 23726 useGrouping: false, 23727 notation: 'compact', 23728 compactDisplay: 'short' 23729 }); 23730 this.svg 23731 .selectAll('.waterfall-bar-labels') 23732 .data(this._data) 23733 .enter() 23734 .append('text') 23735 .attr('class', 'waterfall-bar-labels') 23736 .attr('x', d => this.xScale(d.program) + this.margin.left) 23737 .attr('y', d => this.yScale(Math.max(d.y1, d.y2)) + this.margin.top - 14) 23738 .attr('dx', this.xScale.bandwidth() / 2) 23739 .attr('dy', 0) 23740 .attr('text-anchor', 'middle') 23741 .attr('fill', (d, i) => (i !== this._data.length - 1 ? primary : secondary)) 23742 .attr('font-size', '14px') 23743 .attr('font-weight', 'bold') 23744 .attr('letter-spacing', '0.15px') 23745 .text(d => currencyFormatter.format(d.amount)); 23746 } 23747 23748 destroy = () => { 23749 // any clean up tasks go here 23750 super.destroy(); 23751 }; 23752 23753 updateData = ({ data }) => { 23754 this.data = data; 23755 this.init(); 23756 }; 23757} 23758 23759 23760; 23761////pf: javascript/stats/dashboard.js 23762// eslint-disable-next-line no-redeclare 23763const KpiDashboard = { 23764 rights: {} 23765}; 23766 23767KpiDashboard.initAllTiles = () => { 23768 checkDataPermissions(KpiDashboard.rights); 23769 23770 Object.keys(KpiDashboardTiles).forEach(tileName => { 23771 const tile = KpiDashboardTiles[tileName]; 23772 23773 if (tile.title) { 23774 $(tile.selector).find('.title').text(tile.title); 23775 } 23776 tile.elements.forEach(element => { 23777 if (element.init) { 23778 element.init(element, tile); 23779 } 23780 }); 23781 }); 23782}; 23783 23784KpiDashboard.initTileElement = (tileElement, tile) => { 23785 const { selector, handleRequest, handleResponse, queryParams = {}, ...rest } = tileElement; 23786 const { FILTER_TYPE } = KpiTypes; 23787 const { TIME_PERIOD, FROM_BUDGET, PROGRAM_TYPE, ORDER_BY, SORT_BY }
23787 = FILTER_TYPE; 23788 23789 if (tile.permissionsRequired) { 23790 const hasPermission = roleHasPermission(tile.permissionsRequired); 23791 if (!hasPermission) { 23792 $(tile.selector).toggle(false); 23793 return; 23794 } 23795 } 23796 if (tile.canGroupByBrand) { 23797 KpiDashboard.renderTileToggle(tile); 23798 } 23799 23800 onParentPanelOpen(selector, async () => { 23801 if ($(selector).is('.kpis-initialized')) { 23802 return; 23803 } 23804 23805 $(selector).addClass('kpis-initialized'); 23806 23807 tile.filterOptions.forEach(o => { 23808 if (o.type === TIME_PERIOD) { 23809 queryParams[TIME_PERIOD.key] = o.default_option.value; 23810 } 23811 if (o.type === FROM_BUDGET) { 23812 queryParams[FROM_BUDGET.key] = o.default_option.value; 23813 } 23814 if (o.type === PROGRAM_TYPE) { 23815 queryParams[PROGRAM_TYPE.key] = o.default_option.value; 23816 } 23817 if (o.type === ORDER_BY) { 23818 queryParams[ORDER_BY.key] = o.default_option.value; 23819 } 23820 if (o.type === SORT_BY) { 23821 queryParams[SORT_BY.key] = o.default_option.value; 23822 } 23823 }); 23824 23825 KpiUtils.rerenderTileElement({ 23826 selector, 23827 handleRequest, 23828 handleResponse, 23829 queryParams, 23830 spinner: KpiUtils.spinner($(selector).closest('.kpi-tile-body')), 23831 ...rest 23832 }); 23833 23834 tile.filterMenu = new KpiTileFilter2(tile); 23835 }); 23836}; 23837 23838function roleHasPermission(permissionsRequired) { 23839 const { 23840 admin, 23841 communicationsAdmin, 23842 communicationsMarketingAdmin, 23843 financialAdminEdit, 23844 financialAdminView, 23845 financialAdminViewCash, 23846 ordersAdmin, 23847 programAdmin, 23848 programAdminViewOnly, 23849 rootAdmin, 23850 shopEnterCredits, 23851 systemEngineer, 23852 teamAdmin 23853 } = KpiDashboard.rights; 23854 23855 // has all permissions 23856 if (!permissionsRequired || admin || rootAdmin || systemEngineer) { 23857 return true; 23858 } 23859 23860 for (const permission of permissionsRequired) { 23861 if ( 23862 permission === 'finance-group' && 23863 (financialAdminEdit || financialAdminView || financialAdminViewCash) 23864 ) { 23865 return true; 23866 } 23867 if (permission === 'programs-group' && (programAdmin || programAdminViewOnly)) { 23868 return true; 23869 } 23870 if ( 23871 permission === 'communications-group' && 23872 (communicationsAdmin || communicationsMarketingAdmin) 23873 ) { 23874 return true; 23875 } 23876 if (KpiDashboard.rights[permission]) { 23877 return true; 23878 } 23879 } 23880 23881 return false; 23882} 23883 23884function checkDataPermissions(rights) { 23885 function togglePermissions(element) { 23886 const permissions = $(element).data('permission').split(','); 23887 const hasPermission = roleHasPermission(permissions); 23888 $(element).toggle(hasPermission); 23889 } 23890 23891 // programAdminViewOnly and teamAdmin can only see statistics 23892 function checkStatisticsOnlyPermission() { 23893 const userRoles = Object.keys(rights).filter(key => rights[key] === true); 23894 if (userRoles.length !== 1) return false; 23895 23896 const role = userRoles[0]; 23897 if (role !== 'programAdminViewOnly' && role !== 'teamAdmin') return false; 23898 23899 let permitted = []; 23900 if (role === 'teamAdmin') permitted = ['teamAdmin']; 23901 if (role === 'programAdminViewOnly') permitted = ['programAdminViewOnly', 'programs-group']; 23902 23903 $('.kpi-horizontal-menu [data-permission]').each(function () { 23904 const dataPermissions = $(this).data('permission').split(','); 23905 const hasPermission = dataPermissions.some(r => permitted.indexOf(r) >= 0); 23906 $(this).toggle(hasPermission); 23907 $(this).addClass('selected'); 23908 }); 23909 23910 $('.kpi-dashboard-panel').hide(); 23911 $('.kpi-dashboard-panel').addClass('smp-multi-page-hidden'); 23912 $('.kpi-horizontal-menu .menu-spacer').hide(); 23913 23914 const $statisticsPanel = $('[data-panel-id=statistics]'); 23915 $statisticsPanel.show(); 23916 $statisticsPanel.removeClass('smp-multi-page-hidden'); 23917 $statisticsPanel.find('[data-permission]').each(function () { 23918 togglePermissions(this); 23919 }); 23920 23921 return true; 23922 } 23923 23924 if (checkStatisticsOnlyPermission()) return; 23925 23926 $('[data-permission]').each(function () { 23927 togglePermissions(this); 23928 }); 23929} 23930 23931// eslint-disable-next-line no-redeclare, no-unused-vars 23932KpiDashboard.initializeRevenueExpenseSwitcher = () => { 23933 // Graph/Table switcher 23934 $('input[name="expense_tile_options"]').on('click', function () { 23935 const selectedView = $(this).val(); 23936 // nearest .kpi-tile 23937 const $tileBody = $('#rev-exp-tile-body'); 23938 const height = $tileBody.find('[data-view]').height(); 23939 23940 $tileBody.find('[data-view]').css({ 23941 height: height, 23942 overflow: 'auto' 23943 }); 23944 23945 if (selectedView === 'show_table') { 23946 $tileBody.find('[data-view="chart"]').hide(); 23947 $tileBody.find('[data-view="table"]').show(); 23948 } else { 23949 $tileBody.find('[data-view="chart"]').show(); 23950 $tileBody.find('[data-view="table"]').hide(); 23951 } 23952 }); 23953}; 23954 23955 23956; 23957////pf: javascript/stats/horizontal-scroll.js 23958// eslint-disable-next-line no-redeclare 23959const HorizontalScroller = {}; 23960 23961HorizontalScroller.init = () => { 23962 $('.horizontal-scroll-wrapper').each(function () { 23963 const $this = $(this); // Refer to the current .horizontal-scroll-wrapper in context 23964 23965 $this.on('mousedown', function (e) { 23966 if ($(e.target).closest('.tile__options-menu').length) { 23967 return; // If the clicked element is .tile__options-menu or its ancestor, do nothing 23968 } 23969 23970 e.preventDefault(); 23971 23972 $this 23973 .on('mousemove', function (e) { 23974 e.preventDefault(); 23975 // get current scroll position 23976 let scrollLeft = $this[0].scrollLeft; 23977 23978 // set new scroll position 23979 $this[0].scrollLeft = scrollLeft - e.originalEvent.movementX; 23980 }) 23981 .on('mouseup', function () { 23982 $this.off('mousemove'); 23983 }) 23984 .on('mouseleave', function () { 23985 $this.off('mousemove'); 23986 }); 23987 }); 23988 23989 $(document).on('mousedown', '.tile__options-menu', function (e) { 23990 e.stopPropagation(); // Prevent the mousedown event from bubbling up to the parent element 23991 }); 23992 }); 23993}; 23994 23995 23996; 23997////pf: javascript/stats/day-type-switch.js 23998// eslint-disable-next-line no-redeclare 23999const DayTypeSwitch = {}; 24000
24001DayTypeSwitch.getDateString = () => { 24002 const d = new Date(); 24003 const dateString = d.toLocaleString('default', { month: 'short' }) + ' ' + d.getDate(); 24004 return dateString; 24005}; 24006 24007DayTypeSwitch.setSwitchDateString = () => { 24008 $('#day-type-switch__date-val').text(DayTypeSwitch.getDateString()); 24009}; 24010 24011DayTypeSwitch.switcherAction = async timePeriod => { 24012 const snapshotTiles = getSnapshotTiles(); 24013 24014 // const getAlertContainer = (type, selector) => { 24015 // const { PROGRESS_STATS, SORTABLE_STATS } = KpiTypes.TILE_ELEMENT; 24016 // return type === PROGRESS_STATS || SORTABLE_STATS 24017 // ? $(selector).find('.kpi-progress-list') 24018 // : selector; 24019 // }; 24020 24021 const tilePromises = snapshotTiles.map(async tile => { 24022 tile.elements.forEach(e => { 24023 e.queryParams.timePeriod = timePeriod; 24024 }); 24025 24026 const tileElementPromises = tile.elements.map(async element => { 24027 const { handleRequest, handleResponse, queryParams, selector, ...rest } = element; 24028 24029 KpiUtils.rerenderTileElement({ 24030 selector, 24031 handleRequest, 24032 handleResponse, 24033 queryParams, 24034 ...rest 24035 }); 24036 }); 24037 return Promise.all(tileElementPromises); 24038 }); 24039 24040 await Promise.all(tilePromises); 24041}; 24042 24043DayTypeSwitch.setActiveButton = () => { 24044 const activeClass = 'checked'; 24045 24046 // if url params has Last24Hours=true, then #DayTimeHour should be active 24047 if (window.location.href.indexOf('Last24Hours=true') > -1) { 24048 $('#DayTimeHour').addClass(activeClass); 24049 $('#DayTimeDate').removeClass(activeClass); 24050 KpiTile.spotlightTiles.setIndicators(['Last 24 Hours']); 24051 } else { 24052 $('#DayTimeDate').addClass(activeClass); 24053 $('#DayTimeHour').removeClass(activeClass); 24054 KpiTile.spotlightTiles.setIndicators([`As of today - ${DayTypeSwitch.getDateString()}`]); 24055 } 24056 24057 const $dayTypeSwitch = $('.day-type-switch').children('a'); 24058 $dayTypeSwitch.off('click').on('click', function (e) { 24059 e.preventDefault(); 24060 $dayTypeSwitch.removeClass(activeClass); 24061 $(this).addClass(activeClass); 24062 $(this).blur(); 24063 DayTypeSwitch.switcherAction($(this).data('time-period')); 24064 }); 24065}; 24066 24067DayTypeSwitch.getTimePeriodValue = () => { 24068 const activeClass = 'checked'; 24069 const $dayTypeSwitch = $('.day-type-switch').children('a'); 24070 const $activeButton = $dayTypeSwitch.filter(`.${activeClass}`); 24071 const id = $activeButton.attr('id'); 24072 24073 return id === 'DayTimeHour' 24074 ? KpiTypes.FILTER_TIME_PERIOD.LAST_24_HOURS.value 24075 : KpiTypes.FILTER_TIME_PERIOD.TODAY.value; 24076}; 24077 24078DayTypeSwitch.init = () => { 24079 DayTypeSwitch.setSwitchDateString(); 24080 DayTypeSwitch.setActiveButton(); 24081}; 24082 24083 24084; 24085////pf: javascript/stats/kpi-tile-menu.js 24086// eslint-disable-next-line no-redeclare, no-unused-vars 24087class KpiTileFilter2 { 24088 _selectedValues = {}; 24089 _defaultValues = {}; 24090 _tileIndicatorLabels = []; 24091 _$selectInputs = {}; 24092 $tileFilterMenu = null; 24093 24094 _containerHtml = ` 24095 <div class="tile__options-menu"> 24096 <div class="tile__options-menu__container"></div> 24097 </div> 24098 `; 24099 24100 _filterHtml = ` 24101 <div class="tile__options-menu__item"> 24102 <label for=""></label> 24103 <select></select> 24104 </div> 24105 `; 24106 24107 constructor(tileElement) { 24108 try { 24109 this.tileId = tileElement.selector; 24110 this.filterOptions = [...tileElement.filterOptions]; 24111 this.elements = [...tileElement.elements]; 24112 this.filterOptions.forEach(filter => { 24113 this._selectedValues[filter.type.key] = 24114 filter.default_option.value || filter.options[0].value; 24115 }); 24116 this._tileIndicatorLabels = this.filterOptions.map( 24117 filter => filter.default_option.label || filter.options[0].label 24118 ); 24119 this.init(); 24120 } catch (error) { 24121 console.error(error, { tileElement }); 24122 return; 24123 } 24124 } 24125 24126 init = () => { 24127 const $container = $(this._containerHtml); 24128 24129 for (const [index, filter] of this.filterOptions.entries()) { 24130 const { 24131 type: { label, key }, 24132 default_option, 24133 options, 24134 updateCallback 24135 } = filter; 24136 const $filter = $(this._filterHtml); 24137 const id = `${this.tileId}_${label}`.replace(/[#\s]/g, ''); // remove spaces and # from id 24138 24139 $filter.find('label').attr('for', id).text(label);
24140 const $selectInput = $filter.find('select').attr('id', id); 24141 24142 this._defaultValues[key] = default_option.value || options[0].value; 24143 24144 for (const option of options) { 24145 const $option = $(`<option value="${option.value}">${option.label}</option>`); 24146 if (option.value === this._defaultValues[key]) { 24147 $option.attr('selected', 'selected'); 24148 this.updateTileIndicator(option.label, index); 24149 } 24150 $option.appendTo($selectInput); 24151 } 24152 24153 this.selectHandler($selectInput, options, key, index, updateCallback); 24154 this._$selectInputs[key] = $selectInput; 24155 $container.find('.tile__options-menu__container').append($filter); 24156 } 24157 24158 // show menu when clicking on tile button 24159 const $tileButton = $(this.tileId).find('[data-control="options"]'); 24160 24161 $tileButton.on('click', () => { 24162 $tileButton.parent().append($container); 24163 this.toggle(); 24164 }); 24165 24166 $(document).on('click', event => { 24167 const isInsideContainer = $(event.target).closest($container).length > 0; 24168 const isInsideTileButton = $(event.target).closest($tileButton).length > 0; 24169 24170 if (!isInsideContainer && !isInsideTileButton) { 24171 this.hide(); 24172 } 24173 }); 24174 24175 this.$tileFilterMenu = $container; 24176 }; 24177 24178 selectFilterOption = (key, value) => { 24179 const $selectInput = this._$selectInputs[key]; 24180 const $option = $selectInput.find(`option[value="${value}"]`); 24181 $option.attr('selected', 'selected'); 24182 $selectInput.trigger('change'); 24183 }; 24184 24185 selectHandler = ($selectInput, options, key, index, callback) => { 24186 $selectInput.on('change', event => { 24187 const selectedValue = event.target.value; 24188 const selectedOption = options.find(option => option.value === selectedValue); 24189 24190 this._selectedValues[key] = selectedValue; 24191 $(this.tileId).addClass('tile-is-filtering'); 24192 this.updateTileIndicator(selectedOption.label, index); 24193 if (callback) callback(selectedValue, selectedOption); 24194 24195 this.render(); 24196 this.hide(); 24197 }); 24198 }; 24199 24200 render = async () => { 24201 const promises = this.elements.map(element => { 24202 element.queryParams = { ...element.queryParams, ...this._selectedValues }; 24203 return KpiUtils.rerenderTileElement(element); 24204 }); 24205 await Promise.all(promises); 24206 // console.log('remove class'); 24207 $(this.tileId).removeClass('tile-is-filtering'); 24208 }; 24209 24210 updateTileIndicator = (label, index) => { 24211 this._tileIndicatorLabels[index] = label; 24212 KpiTile.setIndicators(this.tileId, this._tileIndicatorLabels); 24213 }; 24214 24215 hide = () => this.$tileFilterMenu.hide(); 24216 show = () => this.$tileFilterMenu.show(); 24217 toggle = () => this.$tileFilterMenu.toggle(); 24218} 24219 24220 24221; 24222////pf: javascript/stats/kpi-tryouts.js 24223/** 24224 * @file kpi-tryouts.js 24225 * @path www/javascript/stats 24226 * @description This file contains the code for the tryouts panel. 24227 * @functions 24228 * 1. initTryoutsTiles() - Initializes the tiles for tryouts. 24229 * 2. tryoutTileHeader(props) - Generates the header for a specific tryout tile. 24230 * 3. tryoutsNotCalledAlert(props) - Creates the "not called" alert element. 24231 */ 24232 24233/** 24234 * Initializes all of the tryouts tiles. This function is called from /panels/index.js. 24235 */ 24236function initTryoutsTiles() { 24237 // When page is loaded, this attaches the onPanelOpen event listener to the page. 24238 $(document).ready(function () { 24239 let initialized = false; 24240 24241 // This block is executed when the tryouts panel is opened 24242 onPanelOpen(KPI_PANEL.tryouts, async () => { 24243 if (initialized) return; 24244 24245 // This is the big spinner for the tryouts panel 24246 if ($('#kpi-tryouts-loader').length) 24247 $('#kpi-tryouts-loader').remove(); 24248 24249 $('#kpi-tryouts-page').append( 24250 '<div id="kpi-tryouts-loader" class="kpi-tile cols-12" style="min-height: 600px"></div>' 24251 ); 24252 24253 const spinner = KpiUtils.spinner('#kpi-tryouts-loader', { appendToSelf: true }); 24254 spinner.start(); 24255 24256 try { 24257 // ** Fetch and validate the data ** 24258 const data = await KpiData().fetchData('/api/dashboard/tryouts', { 24259 affiliationIds: getAffiliationIds(), count: 12 24260 }); 24261 24262 // error conditions 24263 if (!data || !data.tryouts || !data.tryouts.length) 24264 throw new MissingDataException('Tryouts Panel: no data'); 24265 24266 // Initialize each tile
24267 data.tryouts.forEach((tileData, index) => { 24268 initTryoutTile(tileData, index); 24269 }); 24270 initialized = true; 24271 24272 $('#kpi-tryouts-loader').remove(); 24273 } catch (error) { 24274 // Show error message over the big tile 24275 const tileAlert = KpiUtils._tileElementAlert('#kpi-tryouts-loader', true); 24276 if (error instanceof MissingDataException) { 24277 tileAlert.show('Tryouts Data Currently Unavailable'); 24278 } else { 24279 tileAlert.show(); 24280 } 24281 console.error('initTryoutsTiles: error', error); 24282 } finally { 24283 spinner.end(); 24284 } 24285 }); 24286 }); 24287 24288 /** 24289 * Initializes a single tryout tile. Includes paramaters for: 24290 * - radial gauge 24291 * - progress bar 24292 * - stacked bar graph 24293 * - "not called" alert element (optional) 24294 * @param {string} tileData.title 24295 * @param {URL} tileData.image - URL to the image for the tile 24296 * @param {string} tileData.gaugeLabel - Radial gauge label 24297 * @param {number} tileData.gaugePercentValue - Radial gauge percent value 24298 * @param {string} tileData.gaugeFormattedValue - Radial gauge formatted value 24299 * @param {string} tileData.gaugeSublabel - Radial gauge sublabel 24300 * @param {string} tileData.registrationStatus - 'open' or 'closed' 24301 * @param {number} tileData.barPercentValue - Progress bar percent value 24302 * @param {string} tileData.barFormattedStartDate - Progress bar formatted start date 24303 * @param {string} tileData.barFormattedEndDate - Progress bar formatted end date 24304 * @param {Array} tileData.barGraph - Stacked bar graph data 24305 * @param {number} tileData.notCalledAlertNumber - "Not Called" alert number (of players not called) (optional) 24306 * @param {string} tileData.notCalledAlertTrend - "Not Called" alert trend (up or down) (optional) 24307 * @param {string} tileData.notCalledAlertLink 24308 * @param {number} tileData.retentionValue 24309 * @param {string} tileData.retentionListLink 24310 * @param {number} index - The index of the tile 24311 * 24312 * @param {*} index 24313 * @returns void 24314 */ 24315 function initTryoutTile(tileData, index) { 24316 const todaysDate = new Date().toLocaleDateString('en-US', { 24317 month: 'short', 24318 day: 'numeric', 24319 year: 'numeric' 24320 }); 24321 24322 // Create the tile 24323 const tileProps = { 24324 parent: '#kpi-tryouts-page', 24325 index: index, 24326 tooltip: 'Tryout registration tracking as, as compared to goals, per program.', 24327 title: tileData.title.length > 0 ? 'Tryouts for ' + tileData.title : '', 24328 classNames: 'kpi-tryouts-tile cols-4', 24329 indicators: [todaysDate], 24330 showPercentKey: true 24331 }; 24332 if (tileData.retentionListLink != null) { 24333 tileProps.linkUrl = tileData.retentionListLink; 24334 } 24335 const tile = DashboardTile(tileProps); 24336 tile.render(); 24337 24338 // Create the tile header, which includes the team image, radial gauge, and progress bar 24339 const tileHeader = tryoutTileHeader({ 24340 parent: tile.$element.find('.kpi-tile-body'), 24341 teamImage: tileData.image, 24342 // imageBorderColor: 'var(--primary)', 24343 gaugeLabel: tileData.gaugeLabel, 24344 gaugePercentValue: tileData.gaugePercentValue, 24345 gaugeFormattedValue: tileData.gaugeFormattedValue, 24346 gaugeSublabel: tileData.gaugeSublabel,
24347 registrationStatus: tileData.registrationStatus, 24348 barPercentValue: tileData.barPercentValue, 24349 barFormattedStartDate: tileData.barFormattedStartDate, 24350 barFormattedEndDate: tileData.barFormattedEndDate 24351 }); 24352 tileHeader.render(); 24353 24354 tile.body.append(` 24355 <div class="subheader-group"> 24356 <h3>Registered Athletes vs Goal By Division</h3> 24357 </div> 24358 `); 24359 24360 // Create the stacked bar graph 24361 tile.body.append('<div class="tryout-bar-graph"></div>'); 24362 const barGraphSelector = tile.body.find('.tryout-bar-graph').get(0); 24363 try { 24364 const barGraph = new TryoutsBarGraph({ 24365 selector: barGraphSelector, 24366 options: { 24367 useSmallLabels: true, 24368 viewboxOffsetBottom: -50 24369 }, 24370 data: tileData.barGraph 24371 }); 24372 } catch (error) { 24373 KpiUtils._tileElementAlert(barGraphSelector, true).show(); 24374 } 24375 24376 // If number is present, create the "not called" alert 24377 if (tileData.notCalledAlertNumber) { 24378 if (!tileData.notCalledAlertLink) { 24379 console.error('initTryoutsTiles: no link provided for not called alert'); 24380 return; 24381 } 24382 const notCalledAlert = tryoutsNotCalledAlert({ 24383 indicatorNumber: tileData.notCalledAlertNumber, 24384 indicatorTrend: tileData.notCalledAlertTrend, 24385 linkTo: tileData.notCalledAlertLink 24386 }); 24387 tile.body.append(notCalledAlert); 24388 } 24389 24390 if (tileData.retentionValue != null && tileData.retentionValue > 0) { 24391 const retentionListTile = 24392 `<a href="${tileData.retentionListLink}" target="_blank" class="tryout-retention-box"> 24393 <div class="tryout-retention-number"><i class="fa-solid fa-arrow-down" style="font-size: 30px;align-self: center;"></i> ${tileData.retentionValue}</div> 24394 <div class="tryout-retention-label">Players Not Registered from Last Year's Programming</div> 24395 <div class="tryout-retention-label" style="white-space: nowrap;">Call List <i class="fa-solid fa-chevron-right" style="align-self: center;"></i></div> 24396 </a>` 24397 tile.body.append(retentionListTile); 24398 } 24399 } 24400} 24401 24402/** 24403 * Creates the header for the tryouts tile. Header includes the team image, radial gauge, and progress bar. 24404 * 24405 * @param {object} props 24406 * @param {string} props.parent - Selector for the parent element 24407 * @param {string} props.teamImage - URL to the team image 24408 * @param {string} props.imageBorderColor - Color of the border around the team image 24409 * @param {string} props.gaugeLabel - Radial gauge label 24410 * @param {number} props.gaugePercentValue - Radial gauge percent value 24411 * @param {string} props.gaugeFormattedValue - Radial gauge formatted value 24412 * @param {string} props.gaugeSublabel - Radial gauge sublabel 24413 * @param {string} props.registrationStatus - 'open' or 'closed' 24414 * @param {number} props.barPercentValue - Progress bar percent value 24415 * @param {string} props.barFormattedStartDate - Progress bar formatted start date 24416 * @param {string} props.barFormattedEndDate - Progress bar formatted end date 24417 * 24418 * @returns {Object} An object containing two methods. 24419 * @returns {Function} .render - Renders the header into the specified selector. If no selector is provided, it defaults to the parent specified in props. 24420 * @returns {Function} .destroy - Removes the component from the DOM. 24421 */ 24422function tryoutTileHeader(props) { 24423 const { 24424 parent, 24425 teamImage, 24426 imageBorderColor, 24427 gaugeLabel, 24428 gaugePercentValue, 24429 gaugeFormattedValue, 24430 gaugeSublabel, 24431 registrationStatus, 24432 barPercentValue, 24433 barFormattedStartDate, 24434 barFormattedEndDate 24435 } = props; 24436 24437 const template = ` 24438 <div class="tryout-header"> 24439 <div class="tryout-header-wrapper"> 24440 <div class="tryout-header-image-and-radial"></div> 24441 </div> 24442 </div> 24443 `; 24444 24445 let $element = null; 24446 24447 const init = () => { 24448 $element = $(template); 24449 $element 24450 .find('.tryout-header-image-and-radial') 24451 .append([renderTeamImage(), renderRadialGauge()]); 24452 $element.find('.tryout-header-wrapper').append(renderProgressBar()); 24453 }; 24454 24455 const renderTeamImage = () => { 24456 const style = imageBorderColor ? `style="border: 3px solid ${imageBorderColor}"` : ''; 24457 const $teamImage = $(` 24458 <div class="tryout-team-image"> 24459 <img src="${teamImage}" ${style} alt="tryouts team"> 24460 </div> 24461 `); 24462 return $teamImage; 24463 }; 24464 24465 const renderRadialGauge = () => { 24466 try { 24467 const gaugeColor = gaugePercentValue 24468 ? `var(--${KpiUtils.percentToColorClass(gaugePercentValue)})` 24469 : KpiUtils.colors.secondary; 24470 24471 let _registrationMarkup = ''; 24472 24473 if (registrationStatus === 'open') { 24474 _registrationMarkup = ` 24475 <div class="tryout-status open"> 24476 Registration Open <i class="fas fa-circle-check"></i> 24477 </div> 24478 `; 24479 } else { 24480 _registrationMarkup = ` 24481 <div class="tryout-status closed"> 24482 Registration Closed <i class="fas fa-circle-xmark"></i> 24483 </div> 24484 `; 24485 } 24486 24487 const $radialGroup = $(` 24488 <div class="radial-progress-2"> 24489 <div 24490 radial-progress-2 24491 radius="60" 24492 value="${gaugePercentValue || 0}" 24493 color="${gaugeColor}" 24494 stroke-width="20" 24495 formatted-value="${gaugeFormattedValue || 0}" 24496 offset-label-y="6" 24497 icon="fas fa-clipboard-list"> 24498 </div> 24499 <div class="gauge-description"> 24500 <div class="gauge-title">${gaugeLabel}</div> 24501 <div class="gauge-subtitle">${gaugeSublabel}</div> 24502 ${_registrationMarkup} 24503 </div> 24504 </div> 24505 `); 24506 24507 RadialGauge2.initGauge($radialGroup.find('[radial-progress-2]')); 24508 24509 return $radialGroup; 24510 } catch (error) { 24511 return null; 24512 } 24513 }; 24514 24515 const renderProgressBar = () => { 24516 const color = KpiUtils.percentToColorClass(barPercentValue); 24517 24518 const $progressBarGroup = $('<div class="progress-bar-group"></div>'); 24519 24520 $progressBarGroup.append(` 24521 <div class="tryout-progress-bar"> 24522 <div class="bar bar-future"></div> 24523 <div class="bar bar-past" style="width: ${barPercentValue}%"></div> 24524 <div class="bar bar-present ${color}" style="left: calc(${barPercentValue}% - 16px)"></div> 24525 </div> 24526 `); 24527 24528 $progressBarGroup.append(` 24529 <div class="tryout-progress-bar-labels"> 24530 <div class="start"> 24531 <b>Tryouts Start</b>
24532 <span>${barFormattedStartDate}</span> 24533 </div> 24534 <div class="end"> 24535 <b>Tryouts End</b> 24536 <span>${barFormattedEndDate}</span> 24537 </div> 24538 </div> 24539 `); 24540 24541 return $progressBarGroup; 24542 }; 24543 24544 const render = (selector = parent) => { 24545 $(selector).append($element); 24546 }; 24547 24548 const destroy = () => { 24549 $element.remove(); 24550 }; 24551 24552 init(); 24553 24554 return { 24555 render, 24556 destroy 24557 }; 24558} 24559 24560/** 24561 * Creates the "not called" alert element. 24562 * 24563 * @param {object} props 24564 * @param {number} props.indicatorNumber - number of players not called 24565 * @param {string} props.indicatorTrend - 'up' or 'down', used to determine icon and color 24566 * @param {string} props.linkTo - URL to corresponding retention list 24567 * @returns {jQuery} - The alert jQuery element 24568 */ 24569function tryoutsNotCalledAlert({ indicatorNumber, indicatorTrend, linkTo }) { 24570 const template = ` 24571 <div class="not-called-alert"> 24572 <h3 class="number-indicator"> 24573 <i></i><span class="number"></span> 24574 </h3> 24575 <p class="not-called-alert__text">Players Registered<br />from Last Year</p> 24576 <a href="#" class="call-list-link">Call List <i class="fas fa-chevron-right"></i></a> 24577 </div> 24578 `; 24579 24580 const trend_types = ['up', 'down']; 24581 24582 let $element = null; 24583 24584 const init = () => { 24585 $element = $(template); 24586 $element.find('.number').text(indicatorNumber); 24587 24588 if (!trend_types.includes(indicatorTrend)) { 24589 // There is no default trend type 24590 console.warn( 24591 'TryoutsNotCalledAlert: invalid trend type. Icon and color may not render correctly.' 24592 ); 24593 } 24594 $element.find('.number-indicator i').replaceWith(getIndicatorArrow()); 24595 $element.find('.number-indicator').addClass(getIndicatorColorClass()); 24596 $element.find('.call-list-link').attr('href', linkTo); 24597 }; 24598 24599 const getIndicatorArrow = () => { 24600 if (indicatorTrend === 'up') return '<i class="fas fa-arrow-up">'; 24601 if (indicatorTrend === 'down') return '<i class="fas fa-arrow-down">'; 24602 return ''; 24603 }; 24604 24605 const getIndicatorColorClass = () => { 24606 if (indicatorTrend === 'up') return 'positive'; 24607 if (indicatorTrend === 'down') return 'negative'; 24608 return ''; 24609 }; 24610 24611 init(); 24612 24613 return $element; 24614} 24615 24616class TryoutsBarGraph extends StackedBarGraph2 { 24617 useLabelHoverEffect = true; 24618 24619 constructor(props) { 24620 props.options = { 24621 ...props.options, 24622 height: 350, 24623 margin: { left: 60, bottom: 80 } 24624 }; 24625 super(props); 24626 } 24627} 24628 24629 24630; 24631////pf: javascript/stats/panels/index.js 24632/* eslint-disable no-unused-vars, no-redeclare */ 24633const KpiDashboardTiles = {}; 24634 24635function initTileConfigs() { 24636 initSnapshotTiles(); 24637 initTryoutsTiles(); 24638 initScheduleTile(); 24639 initSalesTiles(); 24640 initArTiles(); 24641 initStatisticsTiles(); 24642 initMarketingTiles(); 24643 24644 /** 24645 * Enable sorting on progress stats. Replaces default handlesort function. 24646 * @param {object} progStatConfig 24647 * @param {string} progStatConfig.selector 24648 * @param {string} progStatConfig.title 24649 * @param {string} progStatConfig.tooltip 24650 * @param {object} progStatConfig.renderProps 24651 * @returns void 24652 */ 24653 const handleSortableProgressStats = progStatConfig => { 24654 let { selector, title, tooltip, renderProps = {} } = progStatConfig; 24655 24656 const handleSort = async showTopResults => { 24657 const spinner = KpiUtils.spinner($(selector).find('.kpi-progress-list'), { 24658 appendToSelf: true 24659 }); 24660 progStatConfig.queryParams = { ...progStatConfig.queryParams, showTopResults }; 24661 await KpiUtils.rerenderTileElement({ ...progStatConfig, spinner }); 24662 }; 24663 24664 const handleResponse = (response, selector, params) => { 24665 ProgressStat.createGroup({ 24666 progressStats: response.stats, 24667 selector, 24668 title: title || undefined, 24669 tooltip: tooltip || undefined, 24670 sorting: true, 24671 handleSort, 24672 params, 24673 ...renderProps 24674 }); 24675 }; 24676 24677 return handleResponse; 24678 }; 24679 24680 const { SORTABLE_STATS } = KpiTypes.TILE_ELEMENT; 24681 const tiles = getDashboardTileArray(); 24682 const sortableStatElements = getTileElementArray().filter(({ type }) => type === SORTABLE_STATS); 24683
24684 sortableStatElements.forEach(element => { 24685 element.handleResponse = handleSortableProgressStats(element); 24686 }); 24687} 24688 24689// Convert KpiDashboardTiles to an array 24690const getDashboardTileArray = () => Object.values(KpiDashboardTiles); 24691 24692// Create an array of tile elements 24693const getTileElementArray = () => { 24694 return getDashboardTileArray().reduce((acc, tile) => { 24695 acc.push(...tile.elements); 24696 return acc; 24697 }, []); 24698}; 24699 24700const getElementBySelector = elSelector => { 24701 return getTileElementArray().filter(({ selector }) => selector === elSelector)[0]; 24702}; 24703 24704const KPI_PANEL = { 24705 spotlight: 'SnapshotPage', 24706 tryouts: 'TryoutsPage', 24707 schedule: 'SchedulePage', 24708 sales: 'SalesPage', 24709 ar: 'ArPage', 24710 statistics: 'RegistrationPage', 24711 marketing: 'CommunicationsPage' 24712}; 24713 24714const onPanelOpen = (id, callback) => { 24715 const panel = document.getElementById(id); 24716 24717 if (panel) { 24718 if (!panel.classList.contains('smp-multi-page-hidden')) { 24719 callback(); 24720 } 24721 24722 const observer = new MutationObserver(function (mutations) { 24723 mutations.forEach(function (mutation) { 24724 if (mutation.attributeName === 'class') { 24725 if ( 24726 mutation.target.classList.contains('kpi-dashboard-panel') && 24727 !mutation.target.classList.contains('smp-multi-page-hidden') 24728 ) { 24729 callback(); 24730 } 24731 } 24732 }); 24733 }); 24734 observer.observe(panel, { 24735 attributes: true 24736 }); 24737 } 24738}; 24739 24740const onPanelToggle = (id, { openCallback, closeCallback }, useInitialCheck) => { 24741 const panel = document.getElementById(id); 24742 if (!panel) return; 24743 24744 const isOpen = () => 24745 panel.classList.contains('kpi-dashboard-panel') && 24746 !panel.classList.contains('smp-multi-page-hidden'); 24747 const isClose = () => 24748 panel.classList.contains('kpi-dashboard-panel') && 24749 panel.classList.contains('smp-multi-page-hidden'); 24750 24751 if (useInitialCheck) { 24752 // initial check will fire callback if panel is open on page load 24753 if (isOpen()) { 24754 openCallback(); 24755 } else if (isClose()) { 24756 closeCallback(); 24757 } 24758 } 24759 24760 const observer = new MutationObserver(mutations => { 24761 mutations.forEach(mutation => { 24762 if (mutation.attributeName === 'class') { 24763 // mutation check 24764 if (isOpen()) { 24765 openCallback(); 24766 } else if (isClose()) { 24767 closeCallback(); 24768 } 24769 } 24770 }); 24771 }); 24772 24773 observer.observe(panel, { 24774 attributes: true 24775 }); 24776}; 24777 24778const onParentPanelOpen = (selector, callback) => { 24779 try { 24780 const parentPanel = $(selector).closest('.kpi-dashboard-panel')[0]; 24781 if (!parentPanel) return; 24782 24783 onPanelOpen(parentPanel.id, callback); 24784 } catch (error) { 24785 console.error(error); 24786 } 24787}; 24788 24789 24790; 24791////pf: javascript/stats/components/schedule/attendance-gauge.js 24792// eslint-disable-next-line no-redeclare, no-unused-vars 24793class AttendanceGauge extends DonutChart { 24794 displayLegend = false; 24795 noSpacers = true; 24796 type = 'attendance-gauge'; 24797 24798 constructor(props) { 24799 super(props); 24800 24801 const { data, options } = props; 24802 24803 this.options.radius = options.radius || 29; 24804 this.options.strokeWidth = options.strokeWidth || 2; 24805 this.options.palette = options.palette; 24806 24807 this.update({ data, options }); 24808 } 24809 24810 update({ data = [], options }) { 24811 this.segments = data; 24812 this.options = options || {}; 24813 this.init(); 24814 } 24815 24816 colorScale = (segment, index) => { 24817 return this.palette[index]; 24818 }; 24819 24820 drawInnerMetric = radius => { 24821 // svg text with x y centered text 24822 const label = ` 24823 <text x='${radius}' y='${radius}' class='inner-label inner-label-event-item'> 24824 <tspan x='${radius + 2}' dy='-0.25em' class='value'>${this.options.innerValue || ''}</tspan> 24825 <tspan x='${radius}' dy='1.1em' class='label'>${this.options.innerLabel || ''}</tspan> 24826 </text> 24827 `; 24828 return label; 24829 }; 24830} 24831 24832 24833; 24834////pf: javascript/stats/components/schedule/attendance-modal.js 24835// eslint-disable-next-line no-redeclare, no-unused-vars 24836function attendanceModal(props) { 24837 const { eventId, attended, gameScheduleID, teamID, eventName } = props; 24838 24839 let _attendees = []; 24840 let _messageAllLink = ''; 24841 let _brandId = ''; 24842 24843 async function fetchAttendanceListAsync() { 24844 try { 24845 const url = `/api/dashboard/schedule/attendance?gameScheduleID=${gameScheduleID}&teamID=${teamID}`; 24846 const response = await fetch(url);
24847 const data = await response.json(); 24848 _attendees = data.attendees; 24849 _messageAllLink = data.messageAllLink; 24850 _brandId = data.brandId; 24851 24852 } catch (error) { 24853 // eslint-disable-next-line no-console 24854 console.error(error); 24855 } 24856 } 24857 24858 const $modal = $(` 24859 <div class="event-attendance-modal" id="event-attendance-modal_${eventId}_${teamID}"> 24860 <h2>Event Attendance - ${eventName}</h2> 24861 <div class="event-attendance-modal-body"></div> 24862 </div> 24863 `); 24864 24865 const formatDateISOtoReadable = dateTime => { 24866 // takes a format like 2023-08-09T13:52:44.913 and returns 8/9/2023 1:52 PM 24867 const date = new Date(dateTime); 24868 const formatted = date.toLocaleString('en-US', { 24869 month: 'numeric', 24870 day: 'numeric', 24871 year: 'numeric', 24872 hour: 'numeric', 24873 minute: 'numeric', 24874 hour12: true 24875 }); 24876 return formatted.replace(',', ''); 24877 }; 24878 24879 const renderAttendanceIcon = status => { 24880 if (status === 'yes') return `<i class="yes fas fa-circle-check"></i>`; 24881 if (status === 'no') return `<i class="no fas fa-circle-x"></i>`; 24882 if (status === 'maybe') return `<i class="maybe fas fa-circle-question"></i>`; 24883 return ''; 24884 }; 24885 24886 const renderAttendeeTable = () => { 24887 // renders Attendance column header 24888 const thAttendance = () => { 24889 const { yes = '0', no = '0', maybe = '0' } = attended; 24890 24891 return ` 24892 Attendance 24893 <span>${renderAttendanceIcon('yes')} ${yes}</span> 24894 <span>${renderAttendanceIcon('no')} ${no}</span> 24895 <span>${renderAttendanceIcon('maybe')} ${maybe}</span> 24896 `; 24897 }; 24898 24899 const $content = $(_attendees.length > 0 24900 ? `<div class="event-attendance-message"> 24901 <div style='display:flex; justify-content: flex-end;'> 24902 <a target='_blank' href='${_messageAllLink}' class='ForwardButton' style='position: relative; margin-right: 5px;' > 24903 <i class='fa-solid fa-envelope'></i><span>Message All</span> 24904 </a> 24905 <button title='Export To Excel' type='button' class='ForwardButton' id='excel-export-button_${eventId}_${teamID}'> 24906 <i class='fa fa-file-export'></i><span>Export to Excel</span> 24907 </button> 24908 </div> 24909 </div>` 24910 : ''); 24911 24912 const $table = $(` 24913 <table class="event-attendance-table"> 24914 <thead> 24915 <tr> 24916 <th>#</th> 24917 <th>Name</th> 24918 <th>Position</th> 24919 <th class="th-attendance">${thAttendance()}</th> 24920 <th>Updated</th> 24921 <th>Message</th> 24922 </tr> 24923 </thead> 24924 <tbody></tbody> 24925 </table> 24926 `); 24927 24928 const createRow = (data, i) => { 24929 // prettier-ignore 24930 const { 24931 nameFirst, 24932 nameLast, 24933 positions, 24934 attendanceYes, 24935 attendanceNo, 24936 lastModified, 24937 messageLink 24938 } = data; 24939 24940 const tdAttendance = () => { 24941 if (attendanceYes) return renderAttendanceIcon('yes'); 24942 if (attendanceNo) return renderAttendanceIcon('no'); 24943 if (!attendanceYes && !attendanceNo) return renderAttendanceIcon('maybe'); 24944 return ``; 24945 }; 24946 24947 const rowMarkup = ` 24948 <tr> 24949 <td>${i + 1}</td> 24950 <td>${nameFirst} ${nameLast}</td> 24951 <td>${positions}</td> 24952 <td class="td-attendance-icon">${tdAttendance()}</td> 24953 <td>${lastModified ? formatDateISOtoReadable(lastModified) : ''}</td> 24954 <td> 24955 <div style='display:flex;'> 24956 <a target='_blank' href='${messageLink}' 24957 title='Message this athlete' class='ForwardButton RoundButton'> 24958 <i class='fa-solid fa-envelope'></i> 24959 </a> 24960 </div> 24961 </td> 24962 </tr> 24963 `; 24964 return rowMarkup; 24965 }; 24966 24967 const rows = _attendees.map((d, i) => createRow(d, i)).join('\n'); 24968 24969 $table.find('tbody').html(rows); 24970 24971 $content.append($table); 24972 return $content; 24973 }; 24974 24975 const renderError = () => 24976 KpiUtils.renderError({ 24977 title: 'No attendance data found.', 24978 message: 'Please try again later.' 24979 }); 24980 24981 const handleClickAsync = async () => { 24982 if (_attendees == null || _attendees.length === 0) await fetchAttendanceListAsync(); 24983 24984 let $content = _attendees.length ? renderAttendeeTable() : renderError(); 24985 24986 $modal.find('.event-attendance-modal-body').html($content); 24987 $('body').append($modal); 24988 24989 var exportExcelButton = document.getElementById(`excel-export-button_${eventId}_${teamID}`); 24990 if (exportExcelButton != null) { 24991 exportExcelButton.addEventListener('click', () => { 24992 ExportDataToExcel(); 24993 }); 24994 } 24995 24996 $(`.event-attendance-modal`).hide(); 24997 24998 return $.fn.modalElement.open({ 24999 target: `#event-attendance-modal_${eventId}_${teamID}` 25000 }); 25001 }; 25002 25003 function ExportDataToExcel() { 25004 const data = [];
25005 _attendees.forEach((item, index) => { 25006 const row = []; 25007 row.push(index + 1); 25008 row.push(item.nameFirst + " " + item.nameLast); 25009 row.push(item.attendanceYes == true ? "Yes" : item.attendanceNo == true ? "No" : "Not Responded"); 25010 row.push(item.lastModified); 25011 data.push(row); 25012 }); 25013 25014 const excelInput = { 25015 columns: ["#", "Name", "Attendance", "Updated"], 25016 valueTypes: ["Number", "Unset", "Unset", "Date"], 25017 data: data, 25018 title: 'Event Attendance - ' + eventName, 25019 affiliationId: _brandId 25020 }; 25021 console.log(excelInput); 25022 25023 const excelPostBack = () => { 25024 fetch(`/api/file/excel`, 25025 { 25026 method: 'POST', 25027 headers: { 25028 'Content-Type': 'application/json' 25029 }, 25030 body: JSON.stringify(excelInput) 25031 }) 25032 .then((res) => { 25033 if (!res.ok) { 25034 return Promise.reject(res); 25035 } 25036 25037 let contentDisposition = res.headers.get('content-disposition'); 25038 let title = (contentDisposition || '').split('filename=\"')[1]; 25039 if (title) 25040 title = title.replace('"', ''); 25041 25042 res.blob() 25043 .then(blob => { 25044 const fileUrl = URL.createObjectURL(blob); 25045 const fileLink = document.createElement('a'); 25046 fileLink.href = fileUrl; 25047 fileLink.download = title; 25048 fileLink.click(); 25049 }); 25050 }); 25051 }; 25052 25053 excelPostBack(); 25054 } 25055 25056 return { 25057 handleClickAsync 25058 }; 25059} 25060 25061 25062; 25063////pf: javascript/stats/components/schedule/event-list-item-group.js 25064// eslint-disable-next-line no-redeclare, no-unused-vars 25065const eventListItemGroup = function (date, events) { 25066 const $element = $(`<div class="schedule__events-list-group"></div>`); 25067 25068 const items = []; 25069 25070 const dateElement = () => { 25071 const formattedDate = new Date(date).toLocaleDateString('en-US', { 25072 month: 'numeric', 25073 day: 'numeric', 25074 year: 'numeric' 25075 }); 25076 25077 const getDayModifier = () => { 25078 const today = new Date(); 25079 const tomorrow = new Date(today); 25080 tomorrow.setDate(tomorrow.getDate() + 1); 25081 const yesterday = new Date(today); 25082 yesterday.setDate(yesterday.getDate() - 1); 25083 25084 if (new Date(date).toDateString() === today.toDateString()) return 'Today'; 25085 if (new Date(date).toDateString() === tomorrow.toDateString()) return 'Tomorrow'; 25086 if (new Date(date).toDateString() === yesterday.toDateString()) return 'Yesterday'; 25087 return new Date(date).toLocaleDateString('en-US', { weekday: 'long' }); 25088 }; 25089 25090 const dayModifier = getDayModifier(); 25091 25092 const markup = ` 25093 <div class="sticky-date modifier-${dayModifier.toLowerCase()}"> 25094 <div><b>${dayModifier}</b></div> 25095 ${formattedDate} 25096 </div> 25097 `; 25098 25099 return `<div class="events-list-group__date">${markup}</div>`; 25100 }; 25101 25102 const $innerList = $(`<div class="events-list-group__items"></div>`); 25103 25104 const render = () => { 25105 $element.append(dateElement()); 25106 $element.append($innerList); 25107 25108 events.forEach(event => { 25109 const $items = eventListItem(event); 25110 $innerList.append($items.render()); 25111 items.push($items); 25112 }); 25113 25114 return $element; 25115 }; 25116 25117 const destroy = () => { 25118 $element.remove(); 25119 items.forEach(item => item.destroy()); 25120 }; 25121 25122 return { 25123 render, 25124 destroy 25125 }; 25126}; 25127 25128 25129; 25130////pf: javascript/stats/components/schedule/event-list-item.js 25131// eslint-disable-next-line no-redeclare, no-unused-vars 25132const eventListItem = function (apiResponse) { 25133 const { 25134 name, 25135 programID, 25136 location, 25137 locationID, 25138 date, 25139 timeStart, 25140 timeEnd, 25141 timeZoneId, 25142 sport, 25143 eventType, 25144 coaches, 25145 team, 25146 teamID, 25147 divisionID, 25148 divisionName, 25149 resizedLogoUrl, 25150 gameScheduleID 25151 } = apiResponse; 25152 25153 let $element = null; 25154 let $attendanceGauge = null; 25155 25156 const eventId = programID; 25157 25158 function formatTimes() { 25159 try { 25160 const startTime = convertScheduleEndpointTime(timeStart); 25161 const endTime = convertScheduleEndpointTime(timeEnd); 25162 return `${startTime} - ${endTime} ${timeZoneId}`; 25163 } catch (error) { 25164 // eslint-disable-next-line no-console 25165 console.error('times not correctly formatted for event: ', apiResponse); 25166 return 'Times TBD'; 25167 } 25168 } 25169 25170 const getMarkupLinkOrLabel = (name, id, linkKey, propertyName) => { 25171 try { 25172 if (name == null || id == null) throw new MissingDataException(`Missing name/id field(s)`); 25173 25174 const url = 25175 linkKey && 25176 id && 25177 generateEventLink({ 25178 key: linkKey, 25179 value: [{ name, value: id }], 25180 date 25181 }); 25182 25183 if (!url) throw new MissingDataException(`Missing url for ${propertyName} ${name || id}`); 25184 25185 return `<a href="${url}" class="no-padding" target="_blank">${name}</a>`; 25186 } catch (error) { 25187 // console.error(`[${propertyName}]: ${error.message}`);
25188 const errorLabel = ` 25189 <span style="font-weight: bold; font-style: italic;" title="${propertyName} not given or missing"> 25190 ${propertyName} TBD<span class="color-danger">*</span> 25191 </span>`; 25192 return errorLabel; 25193 } 25194 }; 25195 25196 // * column A ---------------------------------------- 25197 const renderColumnA = () => { 25198 const getIconEventType = () => { 25199 const pairs = [ 25200 ['Bracket Play', 'fa-kit fa-bracket'], 25201 ['Pool Play', 'fas fa-certificate'], 25202 ['Quarterfinal', 'fas fa-medal'], 25203 ['Semifinal', 'fas fa-medal'], 25204 ['Championship', 'fas fa-trophy'], 25205 ['Practice', 'fas fa-person-running'], 25206 ['Team Meeting', 'fas fa-people-group'], 25207 ['Playoffs', 'fas fa-star'], 25208 ['Other', 'fas fa-flag-pennant'] 25209 ]; 25210 const icon = pairs.find(type => type[0].toLowerCase() === eventType.toLowerCase()); 25211 return icon ? icon[1] : 'fas fa-flag-pennant'; 25212 }; 25213 25214 const fields = [ 25215 { 25216 icon: 'fas fa-clock', 25217 value: formatTimes(), 25218 rowClass: 'times' 25219 }, 25220 { 25221 icon: getIconEventType(), 25222 value: eventType, 25223 rowClass: 'event-type' 25224 }, 25225 { 25226 icon: 'fas fa-map-marker-alt', 25227 value: getMarkupLinkOrLabel(location, locationID, 'SuggestLocation', 'Location'), 25228 rowClass: 'location' 25229 } 25230 ]; 25231 25232 const createRow = ({ icon, value, rowClass }) => ` 25233 <div class="column-item ${rowClass}"> 25234 <div class="icon"> 25235 <i class="${icon}"></i> 25236 </div> 25237 <div class="value">${value}</div> 25238 </div> 25239 `; 25240 25241 const markup = ` 25242 <div class="event-item-column" data-column="1"> 25243 ${fields.map(createRow).join('\n')} 25244 </div> 25245 `; 25246 25247 return markup; 25248 }; 25249 25250 // * column B ---------------------------------------- 25251 const renderColumnB = () => { 25252 const renderLogo = () => { 25253 if (resizedLogoUrl) return `<img src="${resizedLogoUrl}" class="logo" alt="logo">`; 25254 25255 // placeholder 'https://via.placeholder.com/67' 25256 return ` 25257 <div class="logo" title="No image provided"> 25258 <i class="far fa-image"></i> 25259 </div> 25260 `; 25261 }; 25262 25263 const getIconSport = () => { 25264 const pairs = [ 25265 ['Baseball', 'fal fa-baseball'], 25266 ['Fastpitch', 'fal fa-baseball'], 25267 ['Soccer', 'fal fa-futbol'], 25268 ['Football', 'fal fa-football'], 25269 ['Volleyball', 'fal fa-volleyball'], 25270 ['Combat', 'fal fa-hand-fist'], 25271 ['Basketball', 'fal fa-basketball'], 25272 ['Lacrosse', 'fal fa-lacrosse-stick-ball'], 25273 ['Field Hockey', 'fal fa-field-hockey-stick-ball'] 25274 ]; 25275 const icon = pairs.find(type => type[0].toLowerCase() === sport.toLowerCase()); 25276 return icon ? icon[1] : 'fal fa-flag-pennant'; 25277 }; 25278 25279 return ` 25280 <div class="event-item-column" data-column="2"> 25281 ${renderLogo()} 25282 <div class="subtype"> 25283 <i class="${getIconSport()}"></i>${sport} 25284 </div> 25285 </div> 25286 `; 25287 }; 25288 25289 // * column C ---------------------------------------- 25290 const renderColumnC = () => { 25291 const getCoachesMarkup = () => { 25292 let label = 'TBD'; 25293 if (coaches && coaches.length > 0) { 25294 label = coaches.join(', '); 25295 } 25296 return `Coaches: <b>${label}</b>`; 25297 }; 25298 25299 const items = [ 25300 { 25301 value: getCoachesMarkup(), 25302 rowClass: 'coaches' 25303 }, 25304 { 25305 value: `Team: ${getMarkupLinkOrLabel(team, teamID, 'SuggestTeam', 'Team')}`, 25306 rowClass: 'team' 25307 }, 25308 { 25309 value: `Division: ${getMarkupLinkOrLabel( 25310 divisionName, 25311 divisionID, 25312 'SuggestDivision', 25313 'Division' 25314 )}`, 25315 rowClass: 'division' 25316 } 25317 ]; 25318 25319 const createRow = ({ value, rowClass }) => { 25320 const rowMarkup = ` 25321 <div class="column-item ${rowClass}"> 25322 <i class="fa fa-circle"></i>${value} 25323 </div> 25324 `; 25325 return rowMarkup; 25326 }; 25327 25328 const createEventName = () => { 25329 // if (!name && !programID) 25330 //console.warn('Event name and ID missing'); 25331 25332 const eventUrl = 25333 (name && 25334 programID && 25335 generateEventLink({ 25336 key: 'SuggestProgram', 25337 value: [{ name, value: programID }], 25338 date 25339 })) || 25340 null; 25341 25342 const eventName = name || 'Event Name TBD'; 25343 const cssClasses = !eventUrl ? 'link-disabled color-dark' : ''; 25344 const linkStatusIcon = !eventUrl ? `<i class="fas fa-link-slash fa-xs"></i>` : ''; 25345 const titleAttr = !eventUrl ? `title="Event link not yet available."` : ''; 25346 25347 return `
25348 <div class="event-name ${cssClasses}" ${titleAttr}> 25349 <a href="${eventUrl}" target="_blank">${eventName}</a> ${linkStatusIcon} 25350 </div> 25351 `; 25352 }; 25353 25354 const markup = ` 25355 <div class="event-item-column" data-column="3"> 25356 ${createEventName()} 25357 ${items.map(createRow).join('\n')} 25358 </div> 25359 `; 25360 25361 return markup; 25362 }; 25363 25364 const renderColAttendance = attendance => { 25365 if ($attendanceGauge) $attendanceGauge.destroy(); 25366 25367 const palette = []; 25368 const data = []; 25369 25370 function pushAttendance(key, value, color, name) { 25371 if (value > 0) { 25372 palette.push(color); 25373 data.push({ 25374 value: value, 25375 name: name 25376 }); 25377 } 25378 } 25379 25380 pushAttendance('yes', attendance.yes, KpiUtils.colors.positive, 'Yes'); 25381 pushAttendance('no', attendance.no, KpiUtils.colors.negative, 'No'); 25382 pushAttendance('maybe', attendance.maybe, KpiUtils.colors.light, 'Maybe'); 25383 25384 if (!attendance.yes && !attendance.no && !attendance.maybe) { 25385 palette.push('transparent'); 25386 data.push({ 25387 value: 1, 25388 name: 'No Attendance' 25389 }); 25390 } 25391 25392 $attendanceGauge = new AttendanceGauge({ 25393 selector: `.attendance-gauge[data-event="${eventId}"]`, 25394 options: { 25395 innerValue: attendance.total || '0', 25396 innerLabel: 'Athletes', 25397 palette: palette 25398 }, 25399 data: data 25400 }); 25401 25402 const markup = ` 25403 <a href="#" class="link-unstyled event-item-column attendance modal-trigger"> 25404 <div class="attendance-gauge"> 25405 ${$attendanceGauge.html()} 25406 </div> 25407 <ul class="attendance-key"> 25408 <li class="yes">Attend yes: <b>${attendance.yes}</b></li> 25409 <li class="no">Attend no: <b>${attendance.no}</b></li> 25410 <li class="maybe">Attend ?: <b>${attendance.maybe}</b></li> 25411 </ul> 25412 </a> 25413 `; 25414 25415 return markup; 25416 }; 25417 25418 function parseAthleteAttendance(apiResponse) { 25419 let { attended } = apiResponse; 25420 if (!attended) attended = {}; 25421 25422 // if attended.yes is a number and greater than 0, use that number, otherwise use 0 25423 const yes = attended.yes || 0; 25424 const no = attended.no || 0; 25425 const maybe = attended.maybe || 0; 25426 const total = yes + no + maybe; 25427 25428 return { 25429 yes, 25430 no, 25431 maybe, 25432 total 25433 }; 25434 } 25435 25436 const init = () => { 25437 const attendance = parseAthleteAttendance(apiResponse); 25438 25439 $element = $(` 25440 <div class="event-list-item" data-scheduleEvent="${eventId}"> 25441 <div class="event-body"> 25442 ${renderColumnA()} 25443 ${renderColumnB()} 25444 ${renderColumnC()} 25445 ${renderColAttendance(attendance)} 25446 </div> 25447 </div> 25448 `); 25449 25450 const modalProps = { 25451 eventId: eventId, 25452 attended: attendance, 25453 gameScheduleID: gameScheduleID, 25454 teamID: teamID, 25455 eventName: name 25456 }; 25457 25458 const $modalButton = $element.find('.modal-trigger'); 25459 const $modal = attendanceModal(modalProps); 25460 25461 $modalButton.on('click', async e => { 25462 e.preventDefault(); 25463 await $modal.handleClickAsync(); 25464 // can handle loading spinner here 25465 }); 25466 25467 return $element; 25468 }; 25469 25470 return { 25471 render: () => init(), 25472 destroy: () => $element.remove() 25473 }; 25474}; 25475 25476// eslint-disable-next-line no-redeclare 25477function convertScheduleEndpointTime(inputTime) { 25478 // convert this format: "2023-08-10T23:30:00" to "11:30 PM" 25479 const [, time] = inputTime.split('T'); 25480 25481 const [hours, minutes] = time.split(':'); 25482 25483 // Converting hours to 12-hour format 25484 let hours12 = parseInt(hours, 10) % 12; 25485 if (hours12 === 0) { 25486 hours12 = 12; // Convert 0 to 12 for 12-hour clock 25487 } 25488 25489 const period = parseInt(hours, 10) >= 12 ? 'PM' : 'AM'; 25490 25491 const formattedTime = hours12 + ':' + minutes + period; 25492 return formattedTime; 25493} 25494 25495function generateEventLink({ key, value, date }) { 25496 try { 25497 const path = '/util/admin/Teams/schedule/default.aspx'; 25498 25499 const getFromDate = () => { 25500 const fromDate = date ? new Date(date) : new Date(); 25501 fromDate.setDate(fromDate.getDate() - 1); 25502 return fromDate.toISOString(); 25503 }; 25504 25505 // 2 weeks from FromDate 25506 const getToDate = () => { 25507 const toDate = new Date(getFromDate()); 25508 toDate.setDate(toDate.getDate() + 14); 25509 return toDate.toISOString(); 25510 }; 25511
25512 const urlParams = { 25513 EventsToShow: 'All', 25514 FromDate: getFromDate(), 25515 ToDate: getToDate() 25516 }; 25517 25518 // add additional parameters 25519 if (key && value) { 25520 urlParams[key] = JSON.stringify(value); 25521 } else { 25522 //console.warn('generateEventLink: key and value missing. Link will have missing filters.'); 25523 } 25524 25525 const urlString = new URLSearchParams(urlParams); 25526 25527 const href = `${window.location.origin}${path}?${urlString}`; 25528 25529 return href; 25530 } catch (error) { 25531 // eslint-disable-next-line no-console 25532 console.error('generateEventLink error', error); 25533 return null; 25534 } 25535} 25536 25537 25538; 25539////pf: javascript/stats/components/schedule/schedule-body.js 25540// eslint-disable-next-line no-redeclare, no-unused-vars 25541class ScheduleBody { 25542 /** 25543 * The content of the tile body is the main content of the tile. 25544 * @param {Array} props.radialGaugeData - array of radial gauge data from api 25545 * @param {Array} props.eventListData - array of event list data from api 25546 */ 25547 constructor({ radialGaugeData, eventListData, totalCount }) { 25548 this.totalCount = totalCount; 25549 this._radialGauges = []; 25550 this._eventListGroupedByDate = []; 25551 this.radialGaugeData = radialGaugeData; 25552 this.schedule = eventListData; 25553 this.init(); 25554 } 25555 25556 $element = $('#schedule-elements'); 25557 25558 updateData({ radialGaugeData, eventListData, totalCount }) { 25559 this.destroy(); 25560 this.radialGaugeData = radialGaugeData; 25561 this.schedule = eventListData; 25562 this.totalCount = totalCount; 25563 this.init(); 25564 } 25565 25566 refreshEventList(eventListData) { 25567 this.schedule = eventListData; 25568 this.destroyEventList(); 25569 this.renderEvents(eventListData); 25570 } 25571 25572 appendPaginator() { 25573 $('.schedule__paginator').remove(); 25574 this.$element.append('<div class="schedule__paginator"></div>'); 25575 } 25576 25577 init() { 25578 // in order 25579 this.renderDials(); 25580 25581 if (this.totalCount > SCHEDULE_LIST_PAGE_SIZE) { 25582 this.appendPaginator(); 25583 this.renderEvents(this.schedule); 25584 initPaginator('.schedule__paginator', this.totalCount); 25585 } else { 25586 this.renderEvents(this.schedule); 25587 } 25588 25589 this.initialized = true; 25590 } 25591 25592 renderDials() { 25593 if (!this.radialGaugeData || !this.radialGaugeData.length) { 25594 // eslint-disable-next-line no-console 25595 console.warn('No radial gauge data provided'); 25596 return; 25597 } 25598 25599 const $container = $(`<section class="schedule__radials"></section>`); 25600 25601 this.radialGaugeData.forEach((gaugeData, index) => { 25602 const radialGauge = new ScheduleRadial(gaugeData, index); 25603 $container.append($(radialGauge.render())); 25604 this._radialGauges.push(radialGauge); 25605 }); 25606 this.$element.append($container); 25607 25608 RadialGauge2.init(); // initialize all radial gauges 25609 } 25610 25611 renderEvents(schedule) { 25612 const $list = $(`<section id="schedule-events" class="schedule__events"></section>`); 25613 this.$element.append($list); 25614 25615 if (!schedule || !schedule.length) { 25616 // eslint-disable-next-line no-console 25617 console.warn('No schedule data provided'); 25618 $list.css({ height: '100%', padding: 0 }); 25619 return KpiUtils._tileElementAlert('.schedule__events', true).show('No events scheduled.'); 25620 } 25621 25622 schedule.sort((a, b) => new Date(a.date) - new Date(b.date)); 25623 25624 const eventsGroupedByDate = {}; 25625 25626 schedule.forEach(event => { 25627 const { date } = event; 25628 if (!eventsGroupedByDate[date]) { 25629 eventsGroupedByDate[date] = []; 25630 } 25631 eventsGroupedByDate[date].push(event); 25632 }); 25633 25634 Object.keys(eventsGroupedByDate).forEach(date => { 25635 const $group = eventListItemGroup(date, eventsGroupedByDate[date]); 25636 this._eventListGroupedByDate.push($group); 25637 $list.append($group.render()); 25638 }); 25639 } 25640 25641 destroy = () => { 25642 this.$element.empty(); 25643 this._radialGauges.forEach(gauge => gauge.destroy()); 25644 this._radialGauges = []; 25645 this.destroyEventList(); 25646 }; 25647 25648 destroyEventList() { 25649 $('#schedule-events').remove(); 25650 this._eventListGroupedByDate.forEach(group => group.destroy()); 25651 this._eventListGroupedByDate = []; 25652 } 25653} 25654 25655 25656; 25657////pf: javascript/stats/components/schedule/schedule-radial.js 25658// eslint-disable-next-line no-redeclare, no-unused-vars 25659class ScheduleRadial { 25660 constructor(props, index) { 25661 const { gaugeLabel, gaugePercentValue, gaugeFormattedValue, gaugeSublabel } = props; 25662 this.title = gaugeLabel; 25663 this.subtitle = gaugeSublabel; 25664 this.value = gaugePercentValue || 0; 25665 this.formattedValue = gaugeFormattedValue || 0; 25666 this.radius = 60; 25667 this.color = KpiUtils.colors.primary; 25668 this.strokeWidth = 20; 25669 this.offsetLabelY = 6; 25670 this.icon = index === 0 ? 'fas fa-calendar' : 'fas fa-map-marker-alt'; 25671 this.html = null; 25672 } 25673 25674 render() { 25675 this.html = $(` 25676 <div class="schedule-radial radial-progress-2"> 25677 <div 25678 radial-progress-2 25679 radius="${this.radius}" 25680 value="${this.value}" 25681 color="${this.color}" 25682 stroke-width="${this.strokeWidth}" 25683 formatted-value="${this.formattedValue}" 25684 offset-label-y="${this.offsetLabelY}" 25685 icon="${this.icon}"> 25686 </div> 25687 <div class="gauge-description"> 25688 <div class="gauge-title">${this.title}</div> 25689 <div class="gauge-subtitle">${this.subtitle}</div> 25690 </div> 25691 </div> 25692 `); 25693 return this.html; 25694 } 25695 25696 destroy() { 25697 $(this.containerId).empty(); 25698 } 25699} 25700 25701 25702; 25703////pf: javascript/stats/components/schedule/pagination.js 25704async function paginatorCallback(params) { 25705 const tile = KpiDashboardTiles.SCHEDULE; 25706 const tileElement = tile.elements[0]; 25707 tileElement.queryParams = { 25708 ...tileElement.queryParams, 25709 ...params 25710 }; 25711 25712 const { handleRequest, queryParams } = tileElement; 25713 25714 $('#schedule-tile').addClass('tile-is-paginating'); 25715 25716 const handleResponse = async response => { 25717 await tile.schedule_content.refreshEventList(response.eventListData); 25718 $('#schedule-tile').removeClass('tile-is-paginating'); 25719 }; 25720 const alert = KpiUtils._tileElementAlert('#schedule-events', true); 25721 const spinner = KpiUtils.spinner('#schedule-events', { appendToSelf: true });
25722 25723 KpiUtils.rerenderTileElement({ 25724 selector: '#schedule-events', 25725 handleRequest, 25726 queryParams, 25727 handleResponse, 25728 alert, 25729 spinner 25730 }); 25731} 25732 25733/*********************************************************** 25734 * Page initialization 25735 ************************************************************/ 25736// eslint-disable-next-line no-redeclare, no-unused-vars 25737function initPaginator(selector, totalCount) { 25738 try { 25739 const markup = ` 25740 <div class="flex"> 25741 <div class="pagination-info"></div> 25742 25743 <nav class="pagination"> 25744 <button 25745 type="button" 25746 class="pagination-button prev-button" 25747 aria-label="Previous page" 25748 title="Previous page"> 25749 <i class="fas fa-angle-left"></i> 25750 </button> 25751 25752 <div class="pagination-numbers"></div> 25753 25754 <button 25755 type="button" 25756 class="pagination-button next-button" 25757 aria-label="Next page" 25758 title="Next page"> 25759 <i class="fas fa-angle-right"></i> 25760 </button> 25761 </nav> 25762 </div> 25763 `; 25764 25765 $(selector).append(markup); 25766 25767 const options = { 25768 pageSize: SCHEDULE_LIST_PAGE_SIZE, 25769 windowSize: SCHEDULE_LIST_WINDOW_SIZE, 25770 selector 25771 }; 25772 25773 paginate(options, totalCount, async state => { 25774 return paginatorCallback({ 25775 page: state.currentPage, 25776 count: state.pageSize 25777 }); 25778 }); 25779 } catch (error) { 25780 // eslint-disable-next-line no-console 25781 console.error('initPaginator error', error); 25782 } 25783} 25784 25785/*********************************************************** 25786 * Main pagination function 25787 * @param {*} options 25788 * @param {*} options.pageSize - number of items per page 25789 * @param {*} options.windowSize - number of page numbers to show 25790 * @param {*} total - total number of items 25791 * @param {*} callback - callback function to handle page change 25792 ************************************************************/ 25793function paginate(options, total, callback) { 25794 try { 25795 total = total || 0; 25796 25797 const { pageSize, windowSize, selector } = options; 25798 25799 const $container = $(selector); 25800 const $nextButton = $container.find('.next-button'); 25801 const $prevButton = $container.find('.prev-button'); 25802 const $paginationNumbers = $container.find('.pagination-numbers'); 25803 const $paginationInfo = $container.find('.pagination-info'); 25804 25805 const _pageCount = Math.ceil(total / pageSize); 25806 let _currentPage = 1; 25807 25808 const _showNavigatePageButtons = _pageCount > 1; 25809 25810 const getState = () => ({ 25811 total, 25812 pageSize, 25813 currentPage: _currentPage, 25814 pageCount: _pageCount 25815 }); 25816 25817 const toggleButton = ($button, enabled) => { 25818 $button 25819 .toggleClass('disabled', !enabled) 25820 .prop('disabled', !enabled); 25821 }; 25822 25823 /** 25824 * Handle enabling/showing pagination buttons 25825 */ 25826 const handleNavButtonStatus = () => { 25827 toggleButton($prevButton, _currentPage > 1); 25828 toggleButton($nextButton, _currentPage < _pageCount); 25829 }; 25830 25831 const handleNavButtonVisibility = () => { 25832 $prevButton.toggleClass('hidden', !_showNavigatePageButtons); 25833 $nextButton.toggleClass('hidden', !_showNavigatePageButtons); 25834 }; 25835 25836 /** 25837 * Assign active class 25838 */ 25839 const setActivePageClass = () => { 25840 $paginationNumbers.find('.pagination-number').each((i, button) => { 25841 const pageIndex = Number($(button).attr('page-index')); 25842 $(button).toggleClass('active', pageIndex == _currentPage); 25843 }); 25844 }; 25845 25846 /** 25847 * Append page number button to container 25848 * @param {*} index 25849 */ 25850 const appendPageNumber = index => { 25851 const pageNumber = document.createElement('button'); 25852 pageNumber.setAttribute('type', 'button'); 25853 pageNumber.className = 'pagination-number'; 25854 pageNumber.innerHTML = index; 25855 pageNumber.setAttribute('page-index', index); 25856 pageNumber.setAttribute('aria-label', 'Page ' + index); 25857 25858 $paginationNumbers.append(pageNumber); 25859 }; 25860 25861 /** 25862 * Render ellipsis gap between page numbers 25863 */ 25864 const appendGap = () => { 25865 const ellipsis = document.createElement('button'); 25866 ellipsis.setAttribute('type', 'button'); 25867 ellipsis.className = 'pagination-ellipsis'; 25868 ellipsis.innerHTML = '...'; 25869 $paginationNumbers.append(ellipsis); 25870 }; 25871 25872 /** 25873 * Render page number buttons, ellipsis gaps, and attach click handlers 25874 * @param {*} pageIndex 25875 * @returns void 25876 */ 25877 const renderPageNumbers = pageIndex => { 25878 $paginationNumbers.html(''); 25879
25880 const currentSet = Math.ceil(pageIndex / windowSize); 25881 25882 let size = windowSize; 25883 25884 // starting page number 25885 const start = Math.floor((pageIndex - 1) / size) * size + 1; 25886 // max page number 25887 const ceiling = start + size - 1; 25888 // ending page number, if less than max 25889 let end = _pageCount < ceiling ? _pageCount : ceiling; 25890 25891 // number of page numbers to show 25892 const totalSets = Math.ceil(_pageCount / windowSize); 25893 if (totalSets === 1) { 25894 for (let i = start; i <= end; i++) { 25895 appendPageNumber(i); 25896 } 25897 return; 25898 } 25899 25900 const showGapStart = currentSet === totalSets; 25901 const showGapEnd = currentSet < totalSets; 25902 const showGapMid = showGapStart && showGapEnd; 25903 25904 if (showGapStart) { 25905 appendPageNumber(1); 25906 appendGap(); 25907 } 25908 25909 if (showGapMid) { 25910 for (let i = start; i <= end; i++) { 25911 appendPageNumber(i); 25912 } 25913 } else { 25914 for (let i = start; i <= end; i++) { 25915 appendPageNumber(i); 25916 } 25917 } 25918 25919 if (showGapEnd) { 25920 appendGap(); 25921 appendPageNumber(_pageCount); 25922 } 25923 }; 25924 25925 /** 25926 * Find all page number buttons and attach click handlers 25927 */ 25928 const attachPageNumberClickHandlers = () => { 25929 $paginationNumbers.find('.pagination-number').each((i, button) => { 25930 const pageIndex = Number($(button).attr('page-index')); 25931 25932 if (pageIndex) { 25933 $(button).on('click', () => update(pageIndex)); 25934 } 25935 }); 25936 }; 25937 25938 /** 25939 * Set current page and show/hide list items after adding active class and updating nav button status 25940 * @param {*} nextPageNum 25941 */ 25942 const setCurrentPage = nextPageNum => { 25943 _currentPage = nextPageNum; 25944 25945 setActivePageClass(); 25946 handleNavButtonStatus(); 25947 }; 25948 25949 /** 25950 * Update paging info, range and count 25951 */ 25952 const updatePagingInfo = () => { 25953 const currentPageSize = Math.min(pageSize, total - pageSize * (_currentPage - 1)); 25954 $paginationInfo.html(`<h2><span class='record-count'>${currentPageSize.toLocaleString()}/${total.toLocaleString()} Records</span></h2>`); 25955 }; 25956 25957 /** 25958 * Full component update 25959 * @param {*} nextPageNum 25960 */ 25961 const update = async nextPageNum => { 25962 renderPageNumbers(nextPageNum); 25963 setCurrentPage(nextPageNum); 25964 attachPageNumberClickHandlers(); 25965 25966 if (typeof callback === 'function') { 25967 await callback(getState()); 25968 updatePagingInfo(); 25969 } 25970 }; 25971 25972 // Starting point 25973 update(1); 25974 handleNavButtonVisibility(); 25975 updatePagingInfo(); 25976 25977 $prevButton.on('click', () => update(_currentPage - 1)); 25978 $nextButton.on('click', () => update(_currentPage + 1)); 25979 25980 return getState; 25981 } catch (error) { 25982 // eslint-disable-next-line no-console 25983 console.error('Paginator error', error); 25984 } 25985} 25986 25987 25988; 25989////pf: javascript/stats/components/schedule/index.js 25990// eslint-disable-next-line no-redeclare 25991const SCHEDULE_LIST_PAGE_SIZE = 20; 25992// eslint-disable-next-line no-redeclare, no-unused-vars 25993const SCHEDULE_LIST_WINDOW_SIZE = 5; 25994 25995// eslint-disable-next-line no-redeclare, no-unused-vars 25996function initScheduleTile() { 25997 const { FILTER_TIME_PERIOD, FILTER_TYPE, FILTER_PROGRAM_TYPE, program_types_all } = KpiTypes; 25998 const { TODAY, NEXT_WEEK, NEXT_30_DAYS } = FILTER_TIME_PERIOD; 25999 26000 KpiDashboardTiles.SCHEDULE = { 26001 panel: KPI_PANEL.schedule, 26002 selector: '#schedule-tile', 26003 title: 'Scheduled Events', 26004 tooltip: 'Practices, games, or other scheduled events within PlayerFirst.', 26005 elements: [ 26006 { 26007 type: 'SCHEDULE', 26008 selector: '#schedule-elements', 26009 handleRequest: params => { 26010 return KpiData().fetchData('/api/dashboard/schedule', { 26011 ...params, 26012 affiliationIds: getAffiliationIds(), 26013 count: SCHEDULE_LIST_PAGE_SIZE 26014 }); 26015 }, 26016 handleResponse: async response => { 26017 const tile = KpiDashboardTiles.SCHEDULE; 26018 26019 if (!tile.schedule_content) { 26020 return (tile.schedule_content = new ScheduleBody(response)); 26021 } 26022 26023 return tile.schedule_content.updateData(response); 26024 }, 26025 queryParams: {}, 26026 init: KpiDashboard.initTileElement 26027 } 26028 ], 26029 filterOptions: [ 26030 { 26031 type: FILTER_TYPE.TIME_PERIOD, 26032 options: [TODAY, NEXT_WEEK, NEXT_30_DAYS], 26033 default_option: TODAY, 26034 }, 26035 { 26036 type: FILTER_TYPE.PROGRAM_TYPE, 26037 options: program_types_all, 26038 default_option: FILTER_PROGRAM_TYPE.ALL_PROGRAM_TYPES 26039 } 26040 ] 26041 }; 26042 KpiDashboardTiles.SCHEDULE.schedule_content = null; 26043 26044 $(function () { 26045 onPanelToggle( 26046 KPI_PANEL.schedule, 26047 { 26048 openCallback: () => { 26049 $('#MainContent').addClass('unset-overflow'); 26050 }, 26051 closeCallback: () => { 26052 $('#MainContent').removeClass('unset-overflow'); 26053 } 26054 }, 26055 true 26056 ); 26057 }); 26058} 26059 26060; 26061////pf: javascript/stats/toggle-programs-brands.js 26062KpiDashboard.renderTileToggle = tile => { 26063 if ($(tile.selector).is('.has-toggle')) { 26064 return; 26065 } 26066 26067 const $toggle = $(` 26068 <div class="toggle--programs-brands"> 26069 <div class="toggle--programs-brands__container"> 26070 <div class="toggle--programs-brands__item"> 26071 <a data-view='programs' href="#" class="active">Programs</a> 26072 </div> 26073 <div class="toggle--programs-brands__item"> 26074 <a data-view='brands' href="#">Brands</a> 26075 </div> 26076 </div> 26077 </div> 26078 `); 26079 26080 $(tile.selector).find('header:first-child').after($toggle); // insert after header 26081 26082 $(tile.selector) 26083 .find('.toggle--programs-brands a') 26084 .on('click', async function (e) { 26085 e.preventDefault(); 26086 const $a = $(this); 26087 26088 $(tile.selector).find('.toggle--programs-brands a').removeClass('active'); 26089 $a.addClass('active'); 26090 26091 const groupByBrand = $a.data('view') === 'brands';
26092 tile.elements.forEach(el => { 26093 if (el.useBrandToggle) { 26094 el.queryParams = { ...el.queryParams, groupByBrand }; 26095 } 26096 }); 26097 await KpiDashboard.updateTile(tile); 26098 }); 26099 $(tile.selector).addClass('has-toggle'); 26100}; 26101 26102KpiDashboard.shouldTileGroupByBrand = selector => { 26103 return $(selector).find('.toggle--programs-brands a.active').data('view') === 'brands'; 26104}; 26105 26106KpiDashboard.updateTile = async tile => { 26107 const prevTileHeight = $(tile.selector).height(); 26108 26109 await KpiUtils.rerenderTileAllElements(tile); 26110 26111 // before re-rendering tile, set height to previous height if it's bigger than the new height (to prevent jumping) 26112 // else set to auto (to allow for growth) 26113 $(tile.selector).height(prevTileHeight > $(tile.selector).height() ? prevTileHeight : 'auto'); 26114}; 26115 26116 26117; 26118////pf: javascript/stats/panels/snapshot.tiles.js 26119// eslint-disable-next-line no-unused-vars, no-redeclare 26120function initSnapshotTiles() { 26121 const { TODAY } = KpiTypes.FILTER_TIME_PERIOD; 26122 const { DONUT, SORTABLE_STATS } = KpiTypes.TILE_ELEMENT; 26123 26124 KpiDashboardTiles.SNAPSHOT_TILE1 = { 26125 panel: KPI_PANEL.spotlight, 26126 selector: '#Spotlight__Tile1', 26127 title: 'Registrations', 26128 tooltip: 'Individual or team registration details by Activity Type.', 26129 canGroupByBrand: true, 26130 permissionsRequired: ['finance-group', 'ordersAdmin', 'programAdmin'], 26131 elements: [ 26132 { 26133 type: DONUT, 26134 useBrandToggle: true, 26135 selector: '#SpotlightTile1__Donut', 26136 handleRequest: params => 26137 KpiData().fetchData('/api/dashboard/donut/registrations', { 26138 ...params, 26139 affiliationIds: getAffiliationIds() 26140 }), 26141 handleResponse: (response, selector) => { 26142 let tile = KpiDashboardTiles.SNAPSHOT_TILE1; 26143 26144 const donutProps = { 26145 selector, 26146 data: response.segments, 26147 options: { 26148 innerLabel: 'Total Registrations', 26149 innerValue: response.total, 26150 subLabels: response.subLabels 26151 } 26152 }; 26153 26154 if (tile.donut) { 26155 tile.donut.update(donutProps); 26156 } else { 26157 tile.donut = new DonutChart(donutProps); 26158 } 26159 }, 26160 queryParams: { 26161 isTransactional: true, 26162 timePeriod: TODAY.value 26163 }, 26164 init: KpiDashboard.initTileElement 26165 }, 26166 { 26167 type: SORTABLE_STATS, 26168 useBrandToggle: true, 26169 selector: '#SpotlightTile1__ProgressStats', 26170 title: 'Athlete Registration Updates', 26171 tooltip: 26172 'Total & New Individual or Team Registration Numbers based off of the Program Short Name and Time Period. Brand(s) Registered number will include total number of registrations for the calendar year.', 26173 handleRequest: params => 26174 KpiData().fetchData('/api/dashboard/progress/registrations', { 26175 ...params, 26176 affiliationIds: getAffiliationIds() 26177 }), 26178 handleResponse: () => {}, // SORTABLE_STATS set up in initTileConfigs 26179 renderProps: { 26180 options: { 26181 useEndCapLayout: true, 26182 restructuredOrder: true 26183 } 26184 }, 26185 queryParams: { 26186 limit: 4, 26187 timePeriod: TODAY.value 26188 }, 26189 init: KpiDashboard.initTileElement 26190 } 26191 ], 26192 filterOptions: [] 26193 }; 26194 KpiDashboardTiles.SNAPSHOT_TILE1.donut = null; 26195 26196 KpiDashboardTiles.SNAPSHOT_TILE2 = { 26197 panel: KPI_PANEL.spotlight, 26198 selector: '#Spotlight__Tile2', 26199 title: 'Sales', 26200 tooltip: 'Sales by Activity type.', 26201 canGroupByBrand: true, 26202 permissionsRequired: ['finance-group', 'ordersAdmin', 'programAdmin', 'shopEnterCredits'], 26203 elements: [ 26204 { 26205 type: DONUT, 26206 useBrandToggle: true, 26207 selector: '#SpotlightTile2__Donut', 26208 handleRequest: params => 26209 KpiData().fetchData('/api/dashboard/donut/sales', { 26210 ...params, 26211 affiliationIds: getAffiliationIds() 26212 }), 26213 handleResponse: (response, selector) => { 26214 let tile = KpiDashboardTiles.SNAPSHOT_TILE2; 26215 26216 const donutProps = { 26217 data: response.segments, 26218 options: { 26219 innerLabel: 'Total Sales', 26220 innerValue: response.total, 26221 subLabels: response.subLabels 26222 } 26223 }; 26224 26225 if (!tile.donut) { 26226 tile.donut = new DonutChart({ 26227 selector, 26228 ...donutProps 26229 });
26230 } else { 26231 tile.donut.update(donutProps); 26232 } 26233 }, 26234 queryParams: { 26235 isTransactional: true, 26236 timePeriod: TODAY.value 26237 }, 26238 init: KpiDashboard.initTileElement 26239 }, 26240 { 26241 type: SORTABLE_STATS, 26242 useBrandToggle: true, 26243 selector: '#SpotlightTile2__ProgressStats', 26244 title: 'Sales Updates', 26245 tooltip: 26246 'Total & New Sales by a Filtered Period of Time. Brand(s) Invoiced will include total number of registrations for the calendar year.', 26247 handleRequest: params => 26248 KpiData().fetchData('/api/dashboard/progress/sales', { 26249 ...params, 26250 affiliationIds: getAffiliationIds() 26251 }), 26252 handleResponse: () => {}, // SORTABLE_STATS set up in initTileConfigs 26253 renderProps: { 26254 options: { 26255 useEndCapLayout: true, 26256 restructuredOrder: true 26257 } 26258 }, 26259 queryParams: { 26260 limit: 4, 26261 timePeriod: TODAY.value 26262 }, 26263 init: KpiDashboard.initTileElement 26264 } 26265 ], 26266 filterOptions: [] 26267 }; 26268 KpiDashboardTiles.SNAPSHOT_TILE2.donut = null; 26269 26270 KpiDashboardTiles.SNAPSHOT_TILE3 = { 26271 panel: KPI_PANEL.spotlight, 26272 selector: '#Spotlight__Tile3', 26273 title: 'Payments', 26274 tooltip: 'Payment summaries by payment method. Totals include fees.', 26275 canGroupByBrand: true, 26276 permissionsRequired: ['finance-group', 'ordersAdmin', 'programAdmin', 'shopEnterCredits'], 26277 elements: [ 26278 { 26279 type: DONUT, 26280 useBrandToggle: true, 26281 selector: '#SpotlightTile3__Donut', 26282 handleRequest: params => 26283 KpiData().fetchData('/api/dashboard/donut/payments', { 26284 ...params, 26285 affiliationIds: getAffiliationIds() 26286 }), 26287 handleResponse: (response, selector) => { 26288 let tile = KpiDashboardTiles.SNAPSHOT_TILE3; 26289 26290 const donutProps = { 26291 options: { 26292 innerLabel: 'Total Paid', 26293 innerValue: response.total, 26294 subLabels: response.subLabels 26295 }, 26296 data: response.segments 26297 }; 26298 26299 if (!tile.donut) { 26300 tile.donut = new DonutChart({ 26301 selector, 26302 ...donutProps 26303 }); 26304 } else { 26305 tile.donut.update(donutProps); 26306 } 26307 }, 26308 queryParams: { 26309 isTransactional: true, 26310 timePeriod: TODAY.value 26311 }, 26312 init: KpiDashboard.initTileElement 26313 }, 26314 { 26315 type: SORTABLE_STATS, 26316 useBrandToggle: true, 26317 selector: '#SpotlightTile3__ProgressStats', 26318 title: 'Payment Updates', 26319 tooltip: 26320 'Total & New Payments by a Filtered Period of Time. Brand(s) Paid will include total amount paid for the calendar year. Totals do NOT include fees.', 26321 handleRequest: params => 26322 KpiData().fetchData('/api/dashboard/progress/payments', { 26323 ...params, 26324 affiliationIds: getAffiliationIds() 26325 }), 26326 handleResponse: () => {}, // SORTABLE_STATS set up in initTileConfigs 26327 renderProps: { 26328 options: { 26329 useEndCapLayout: true, 26330 restructuredOrder: true 26331 } 26332 }, 26333 queryParams: { 26334 timePeriod: TODAY.value, 26335 showTopResults: true 26336 }, 26337 init: KpiDashboard.initTileElement 26338 } 26339 ], 26340 filterOptions: [] 26341 }; 26342 KpiDashboardTiles.SNAPSHOT_TILE3.donut = null; 26343 26344 KpiDashboardTiles.SNAPSHOT_TILE4 = { 26345 panel: KPI_PANEL.spotlight, 26346 selector: '#Spotlight__Tile4', 26347 title: 'Marketing Emails', 26348 tooltip: 'Total marketing emails sent and opened within a filtered period of time, listed by program. If multiple programs were tagged to the same email, the total recipients across all related programs will be reflected in each line below.', 26349 canGroupByBrand: true, 26350 permissionsRequired: ['communications-group'], 26351 elements: [ 26352 { 26353 type: DONUT, 26354 useBrandToggle: true, 26355 selector: '#SpotlightTile4__Donut', 26356 handleRequest: params => 26357 KpiData().fetchData('/api/dashboard/donut/emails', { 26358 ...params, 26359 affiliationIds: getAffiliationIds() 26360 }), 26361 handleResponse: (response, selector) => { 26362 let tile = KpiDashboardTiles.SNAPSHOT_TILE4; 26363 26364 const donutProps = { 26365 options: { 26366 innerLabel: 'Open Rate', 26367 innerValue: response.total, 26368 subLabels: response.subLabels, 26369 palette: 'byPercent' 26370 }, 26371 data: response.segments 26372 }; 26373 26374 if (!tile.donut) { 26375 tile.donut = new DonutChart({ 26376 selector, 26377 ...donutProps 26378 });
26379 } else { 26380 tile.donut.update(donutProps); 26381 } 26382 }, 26383 queryParams: { 26384 isTransactional: false, 26385 timePeriod: TODAY.value 26386 }, 26387 init: KpiDashboard.initTileElement 26388 }, 26389 { 26390 type: SORTABLE_STATS, 26391 useBrandToggle: true, 26392 selector: '#SpotlightTile4__ProgressStats', 26393 title: 'Open Rate For Most Recent Emails', 26394 tooltip: 'Total marketing emails sent & opened by a filtered period of time.', 26395 handleRequest: params => 26396 KpiData().fetchData('/api/dashboard/progress/emails', { 26397 ...params, 26398 affiliationIds: getAffiliationIds() 26399 }), 26400 handleResponse: () => {}, // SORTABLE_STATS set up in initTileConfigs 26401 renderProps: { 26402 options: { 26403 useEndCapLayout: true 26404 } 26405 }, 26406 queryParams: { 26407 isTransactional: false, 26408 limit: 4, 26409 timePeriod: TODAY.value 26410 }, 26411 init: KpiDashboard.initTileElement 26412 } 26413 ], 26414 filterOptions: [] 26415 }; 26416 KpiDashboardTiles.SNAPSHOT_TILE4.donut = null; 26417 26418 KpiDashboardTiles.SNAPSHOT_TILE5 = { 26419 panel: KPI_PANEL.spotlight, 26420 selector: '#Spotlight__Tile5', 26421 title: 'Transactional Emails', 26422 tooltip: 'Total transactional emails sent and opened within a filtered period of time, listed by program. If multiple programs were tagged to the same email, the total recipients across all related programs will be reflected in each line below.', 26423 permissionsRequired: ['communicationsAdmin'], 26424 canGroupByBrand: true, 26425 elements: [ 26426 { 26427 type: DONUT, 26428 useBrandToggle: true, 26429 selector: '#SpotlightTile5__Donut', 26430 handleRequest: params => 26431 KpiData().fetchData('/api/dashboard/donut/emails', { 26432 ...params, 26433 affiliationIds: getAffiliationIds() 26434 }), 26435 handleResponse: (response, selector) => { 26436 let tile = KpiDashboardTiles.SNAPSHOT_TILE5; 26437 26438 const donutProps = { 26439 options: { 26440 innerLabel: 'Open Rate', 26441 innerValue: response.total, 26442 subLabels: response.subLabels, 26443 palette: 'byPercent' 26444 }, 26445 data: response.segments 26446 }; 26447 26448 if (!tile.donut) { 26449 tile.donut = new DonutChart({ 26450 selector, 26451 ...donutProps 26452 }); 26453 } else { 26454 tile.donut.update(donutProps); 26455 } 26456 }, 26457 queryParams: { 26458 isTransactional: true, 26459 timePeriod: TODAY.value 26460 }, 26461 init: KpiDashboard.initTileElement 26462 }, 26463 { 26464 type: SORTABLE_STATS, 26465 useBrandToggle: true, 26466 selector: '#SpotlightTile5__ProgressStats', 26467 title: 'Open Rate For Most Recent Emails', 26468 tooltip: 'Total transactional emails sent & opened by a filtered period of time.', 26469 handleRequest: params => 26470 KpiData().fetchData('/api/dashboard/progress/emails', { 26471 ...params, 26472 affiliationIds: getAffiliationIds() 26473 }), 26474 handleResponse: () => {}, // SORTABLE_STATS set up in initTileConfigs 26475 renderProps: { 26476 options: { 26477 useEndCapLayout: true 26478 } 26479 }, 26480 queryParams: { 26481 isTransactional: true, 26482 limit: 4, 26483 timePeriod: TODAY.value 26484 }, 26485 init: KpiDashboard.initTileElement 26486 } 26487 ], 26488 filterOptions: [] 26489 }; 26490 KpiDashboardTiles.SNAPSHOT_TILE5.donut = null; 26491 26492 $(function () { 26493 const $tiles = KpiUtils.findVisibleTiles('#kpi-spotlight-page'); 26494 26495 if ($tiles.length > 0) { 26496 if ($tiles.length <= 2 || $tiles.length === 4) { 26497 $tiles.each(function () { 26498 KpiUtils.removeColumnClasses(this); 26499 $(this).addClass('cols-6'); 26500 KpiUtils.unsplitTile(this); 26501 }); 26502 } 26503 26504 if ($tiles.length === 3) { 26505 $tiles.each(function () { 26506 KpiUtils.removeColumnClasses(this); 26507 $(this).addClass('cols-4'); 26508 KpiUtils.unsplitTile(this); 26509 }); 26510 } 26511 } 26512 }); 26513} 26514 26515// eslint-disable-next-line no-redeclare, no-unused-vars 26516function getSnapshotTiles() { 26517 const ids = $(`#${KPI_PANEL.spotlight} .kpi-tile`) 26518 .map(function () { 26519 return `#${this.id}`; 26520 }) 26521 .get(); 26522 return Object.values(KpiDashboardTiles).filter(function (tile) { 26523 return ids.includes(tile.selector); 26524 }); 26525} 26526 26527 26528; 26529////pf: javascript/stats/panels/sales.tiles.js 26530// eslint-disable-next-line no-redeclare, no-unused-vars 26531function initSalesTiles() { 26532 const { 26533 TILE_ELEMENT, 26534 FILTER_TIME_PERIOD, 26535 FILTER_PROGRAM_TYPE, 26536 // FILTER_BUDGET, 26537 FILTER_TYPE, 26538 FILTER_ORDER_BY,
26539 FILTER_SORT_BY, 26540 FILTER_PROGRAM_ACTIVE, 26541 time_periods_lifetime_to_last30, 26542 time_periods_current_fiscal_to_next30, 26543 // budgets_all, 26544 program_types_all 26545 } = KpiTypes; 26546 26547 const { LOW_TO_HIGH, HIGH_TO_LOW } = FILTER_ORDER_BY; 26548 const { SORT_BY_PROFIT, SORT_BY_REVENUE, SORT_BY_EXPENSE } = FILTER_SORT_BY; 26549 const { CURRENT_FISCAL_YEAR, LAST_YEAR, LAST_30_DAYS, NEXT_12_MONTHS } = FILTER_TIME_PERIOD; 26550 const { ALL_PROGRAM_TYPES } = FILTER_PROGRAM_TYPE; 26551 // const { PER_2 } = FILTER_BUDGET; 26552 const { PROGRAM_TYPE, TIME_PERIOD, ORDER_BY, SORT_BY, PROGRAM_ACTIVE } = FILTER_TYPE; 26553 const { SHOW_ALL, SHOW_ONLY_ACTIVE } = FILTER_PROGRAM_ACTIVE; 26554 const { ECON_UNIT, STACKED_BARS, WATERFALL, REV_VS_EXPENSE, TABLE, DONUT, PROGRESS_STATS } = 26555 TILE_ELEMENT; 26556 26557 // 26558 // Permissions are handled at the panel level 26559 // ============================================================ 26560 26561 KpiDashboardTiles.FINANCE_AVG_PURCHASE_PRICE = { 26562 panel: KPI_PANEL.sales, 26563 selector: '#TileEU1', 26564 title: 'Avg. Purchase Price', 26565 tooltip: 'High-level average purchase price.', 26566 elements: [ 26567 { 26568 type: ECON_UNIT, 26569 selector: '#TileEU1__EconomicUnits', 26570 handleRequest: params => 26571 KpiData().fetchData('/api/dashboard/tile/purchaseprice', { 26572 affiliationIds: getAffiliationIds(), 26573 timePeriod: params.timePeriod 26574 }), 26575 handleResponse: (response, selector) => { 26576 EconomicUnit.createGroup({ 26577 selector, 26578 data: response.tiles 26579 }); 26580 }, 26581 init: KpiDashboard.initTileElement 26582 } 26583 ], 26584 filterOptions: [ 26585 { 26586 type: TIME_PERIOD, 26587 options: time_periods_lifetime_to_last30, 26588 default_option: LAST_30_DAYS 26589 } 26590 ] 26591 }; 26592 26593 KpiDashboardTiles.FINANCE_AVG_COMMITTED_REVENUE_PER_PROGRAM = { 26594 panel: KPI_PANEL.sales, 26595 selector: '#TileEU2', 26596 title: 'Committed Revenue Per Program', 26597 tooltip: 'High-level committed revenue per program.', 26598 elements: [ 26599 { 26600 type: ECON_UNIT, 26601 selector: '#TileEU2__EconomicUnits', 26602 handleRequest: params => 26603 KpiData().fetchData('/api/dashboard/tile/programrevenue', { 26604 affiliationIds: getAffiliationIds(), 26605 timePeriod: params.timePeriod 26606 }), 26607 handleResponse: (response, selector) => { 26608 EconomicUnit.createGroup({ 26609 selector, 26610 data: response.tiles 26611 }); 26612 }, 26613 init: KpiDashboard.initTileElement 26614 } 26615 ], 26616 filterOptions: [ 26617 { 26618 type: TIME_PERIOD, 26619 options: time_periods_lifetime_to_last30, 26620 default_option: LAST_30_DAYS 26621 } 26622 ] 26623 }; 26624 26625 KpiDashboardTiles.FINANCE_AVG_REGISTRATION_COSTS = { 26626 panel: KPI_PANEL.sales, 26627 selector: '#TileEU3', 26628 title: 'Avg. Registration Costs', 26629 tooltip: 'High-level average registration costs.', 26630 elements: [ 26631 { 26632 type: ECON_UNIT, 26633 selector: '#TileEU3__EconomicUnits', 26634 handleRequest: params => 26635 KpiData().fetchData('/api/dashboard/tile/regcosts', { 26636 affiliationIds: getAffiliationIds(), 26637 timePeriod: params.timePeriod 26638 }), 26639 handleResponse: (response, selector) => { 26640 EconomicUnit.createGroup({ 26641 selector, 26642 data: response.tiles 26643 }); 26644 }, 26645 init: KpiDashboard.initTileElement 26646 } 26647 ], 26648 filterOptions: [ 26649 { 26650 type: TIME_PERIOD, 26651 options: time_periods_lifetime_to_last30, 26652 default_option: LAST_30_DAYS 26653 } 26654 ] 26655 }; 26656 26657 KpiDashboardTiles.FINANCE_AVG_ADMISSION_COSTS = { 26658 panel: KPI_PANEL.sales, 26659 selector: '#TileEU4', 26660 title: 'Avg. Admission Costs', 26661 tooltip: 'High-level Admission costs.', 26662 elements: [ 26663 { 26664 type: ECON_UNIT, 26665 selector: '#TileEU4__EconomicUnits', 26666 handleRequest: params => 26667 KpiData().fetchData('/api/dashboard/tile/gatecosts', { 26668 affiliationIds: getAffiliationIds(), 26669 timePeriod: params.timePeriod 26670 }), 26671 handleResponse: (response, selector) => { 26672 EconomicUnit.createGroup({ 26673 selector, 26674 data: response.tiles 26675 }); 26676 }, 26677 init: KpiDashboard.initTileElement 26678 } 26679 ], 26680 filterOptions: [ 26681 { 26682 type: TIME_PERIOD, 26683 options: time_periods_lifetime_to_last30, 26684 default_option: LAST_30_DAYS 26685 } 26686 ] 26687 }; 26688 26689 // TODO: No API endpoint for this tile yet ??? 26690 KpiDashboardTiles.FINANCE_AVG_FEES = { 26691 panel: KPI_PANEL.sales, 26692 selector: '#TileEU5', 26693 title: 'Avg. Fees', 26694 tooltip: 'Average fees applied per invoice or athlete.', 26695 elements: [ 26696 { 26697 type: ECON_UNIT, 26698 selector: '#TileEU5__EconomicUnits', 26699 handleRequest: () => console.warn('No API endpoint for this tile yet'), 26700 handleResponse: (response, selector) => { 26701 EconomicUnit.createGroup({ 26702 selector, 26703 data: response.tiles 26704 });
26705 } 26706 } 26707 ], 26708 filterOptions: [ 26709 { 26710 type: TIME_PERIOD, 26711 options: time_periods_lifetime_to_last30, 26712 default_option: LAST_30_DAYS 26713 } 26714 ] 26715 }; 26716 26717 KpiDashboardTiles.FINANCE_TOP_PROGRAMS = { 26718 panel: KPI_PANEL.sales, 26719 selector: '#Revenue__Tile2', 26720 title: 'Top Performing Programs - Revenue', 26721 tooltip: 'Top program or brand by revenue.', 26722 canGroupByBrand: true, 26723 elements: [ 26724 { 26725 type: PROGRESS_STATS, 26726 useBrandToggle: true, 26727 selector: '#RevenueTile2__ProgressStats', 26728 queryParams: { 26729 limit: 4, 26730 showTopResults: true, 26731 fromBudget: 2 26732 }, 26733 handleRequest: params => 26734 KpiData().fetchData('/api/dashboard/progress/programrevenue', { 26735 ...params, 26736 affiliationIds: getAffiliationIds() 26737 }), 26738 handleResponse: (response, selector) => { 26739 ProgressStat.createGroup({ 26740 selector, 26741 progressStats: response.stats, 26742 options: { 26743 restructuredOrder: true 26744 } 26745 }); 26746 }, 26747 init: KpiDashboard.initTileElement 26748 } 26749 ], 26750 filterOptions: [ 26751 { 26752 type: TIME_PERIOD, 26753 options: time_periods_lifetime_to_last30, 26754 default_option: LAST_YEAR 26755 } 26756 // { 26757 // type: FROM_BUDGET, 26758 // options: budgets_all, 26759 // default_option: PER_2 26760 // } 26761 ] 26762 }; 26763 26764 KpiDashboardTiles.FINANCE_REVENUE_VS_EXPENSE = { 26765 panel: KPI_PANEL.sales, 26766 selector: '#Revenue__Tile__revVsExp', 26767 title: 'All Sales vs Serviced Expenses', 26768 tooltip: 26769 'Shows all sales and serviced expenses for programs compared to budget.Revenue is from PlayerFirst, expense and budgets are coming from external data. Data is generated based on programs run during the selected duration. Fiscal year start date is set in the Orders tab of Site Settings.', 26770 canGroupByBrand: true, 26771 elements: [ 26772 { 26773 type: REV_VS_EXPENSE, 26774 useBrandToggle: true, 26775 selector: '#RevenueVsExpenseGraph', 26776 handleRequest: params => 26777 KpiData().fetchData('/api/dashboard/revenueandexpense', { 26778 ...params, 26779 affiliationIds: getAffiliationIds() 26780 }), 26781 handleResponse: (response, selector) => { 26782 const tile = KpiDashboardTiles.FINANCE_REVENUE_VS_EXPENSE; 26783 26784 const props = { 26785 selector, 26786 data: response.stats 26787 }; 26788 26789 if (!tile.graph) { 26790 tile.graph = new RevenueVsExpenseGraph(props); 26791 } else { 26792 tile.graph.updateData(props); 26793 } 26794 }, 26795 init: KpiDashboard.initTileElement 26796 } 26797 ], 26798 filterOptions: [ 26799 { 26800 type: TIME_PERIOD, 26801 options: time_periods_lifetime_to_last30, 26802 default_option: CURRENT_FISCAL_YEAR 26803 }, 26804 { 26805 type: ORDER_BY, 26806 options: [LOW_TO_HIGH, HIGH_TO_LOW], 26807 default_option: HIGH_TO_LOW 26808 }, 26809 { 26810 type: SORT_BY, 26811 options: [SORT_BY_PROFIT, SORT_BY_REVENUE, SORT_BY_EXPENSE], 26812 default_option: SORT_BY_PROFIT 26813 }, 26814 { 26815 type: PROGRAM_TYPE, 26816 options: program_types_all, 26817 default_option: ALL_PROGRAM_TYPES 26818 } 26819 ] 26820 }; 26821 KpiDashboardTiles.FINANCE_REVENUE_VS_EXPENSE.graph = null; 26822 26823 KpiDashboardTiles.FINANCE_BOTTOM_PROGRAMS = { 26824 panel: KPI_PANEL.sales, 26825 selector: '#Revenue__Tile4', 26826 title: 'Bottom Performing Programs - Revenue', 26827 tooltip: 'Bottom program or brand by revenue.', 26828 canGroupByBrand: true, 26829 elements: [ 26830 { 26831 type: PROGRESS_STATS, 26832 useBrandToggle: true, 26833 selector: '#RevenueTile4__ProgressStats', 26834 queryParams: { 26835 limit: 4, 26836 showTopResults: false, 26837 fromBudget: 2 26838 }, 26839 handleRequest: params => 26840 KpiData().fetchData('/api/dashboard/progress/programrevenue', { 26841 ...params, 26842 affiliationIds: getAffiliationIds() 26843 }), 26844 handleResponse: (response, selector) => { 26845 ProgressStat.createGroup({ 26846 selector, 26847 progressStats: response.stats, 26848 options: { 26849 restructuredOrder: true 26850 } 26851 }); 26852 }, 26853 init: KpiDashboard.initTileElement 26854 } 26855 ], 26856 filterOptions: [ 26857 { 26858 type: TIME_PERIOD, 26859 options: time_periods_lifetime_to_last30, 26860 default_option: LAST_YEAR 26861 } 26862 // { 26863 // type: FROM_BUDGET, 26864 // options: budgets_all, 26865 // default_option: PER_2 26866 // } 26867 ] 26868 }; 26869 26870 KpiDashboardTiles.FINANCE_PREVIOUS_VS_NEW_ATHLETES = { 26871 panel: KPI_PANEL.sales, 26872 selector: '#Finance__RegVsNewAthleteRevenue', 26873 title: 'New vs Existing Customers', 26874 tooltip: 26875 'Comparison of registrants to the brand vs. previously registered for a program - revenue based.', 26876 elements: [ 26877 { 26878 type: DONUT, 26879 selector: '#Finance__RegVsNewAthleteRevenue__Donut', 26880 handleRequest: params => 26881 KpiData().fetchData('/api/dashboard/donut/financial_registrations', { 26882 ...params, 26883 affiliationIds: getAffiliationIds() 26884 }), 26885 handleResponse: (response, selector) => { 26886 new DonutChart({ 26887 selector, 26888 data: response.segments, 26889 options: {
26890 innerLabel: 'Registrations', 26891 innerValue: response.total, 26892 subLabels: response.subLabels 26893 } 26894 }); 26895 }, 26896 queryParams: { 26897 isTransactional: true, 26898 programTypes: 'All' 26899 }, 26900 init: KpiDashboard.initTileElement 26901 } 26902 ], 26903 filterOptions: [ 26904 { 26905 type: TIME_PERIOD, 26906 options: time_periods_lifetime_to_last30, 26907 default_option: CURRENT_FISCAL_YEAR 26908 } 26909 ] 26910 }; 26911 26912 KpiDashboardTiles.FINANCE_SALES_VS_BUDGET = { 26913 panel: KPI_PANEL.sales, 26914 selector: '#Revenue__Tile6', 26915 title: 'Deferred Revenue vs Budget', 26916 tooltip: 'Current sales against budget per month.', 26917 elements: [ 26918 { 26919 type: STACKED_BARS, 26920 selector: '#RevenueTile6__StackedBarGraph', 26921 handleRequest: params => 26922 KpiData().fetchData('/api/dashboard/bargraph/salesvbudget', { 26923 ...params, 26924 affiliationIds: getAffiliationIds() 26925 }), 26926 handleResponse: (response, selector, params) => { 26927 let tile = KpiDashboardTiles.FINANCE_SALES_VS_BUDGET; 26928 26929 const barGraphProps = { 26930 data: response.data, 26931 options: { 26932 ...response.options, 26933 useMonthsFormat: true 26934 }, 26935 params 26936 }; 26937 26938 if (tile.stacked_bar_graph) { 26939 tile.stacked_bar_graph.updateData(barGraphProps); 26940 return; 26941 } else { 26942 tile.stacked_bar_graph = new StackedBarGraph2({ 26943 ...barGraphProps, 26944 selector 26945 }); 26946 } 26947 }, 26948 init: KpiDashboard.initTileElement 26949 } 26950 ], 26951 filterOptions: [ 26952 { 26953 type: TIME_PERIOD, 26954 options: time_periods_current_fiscal_to_next30, 26955 default_option: NEXT_12_MONTHS 26956 } 26957 ] 26958 }; 26959 KpiDashboardTiles.FINANCE_SALES_VS_BUDGET.stacked_bar_graph = null; 26960 26961 KpiDashboardTiles.FINANCE_SHORTFALL_WATERFALL = { 26962 panel: KPI_PANEL.sales, 26963 selector: '#Revenue__Tile7', 26964 title: 'Shortfall $ Waterfall By Program', 26965 tooltip: 'Shortfall money breakdown by program or brand segments', 26966 canGroupByBrand: true, 26967 elements: [ 26968 { 26969 type: WATERFALL, 26970 useBrandToggle: true, 26971 selector: '#ShortfallWaterfallByProgram', 26972 handleRequest: params => 26973 KpiData().fetchData('/api/dashboard/shortfall/waterfall', { 26974 ...params, 26975 affiliationIds: getAffiliationIds() 26976 }), 26977 handleResponse: (response, selector) => { 26978 const tile = KpiDashboardTiles.FINANCE_SHORTFALL_WATERFALL; 26979 26980 const graphProps = { 26981 selector, 26982 data: response.stats 26983 }; 26984 if (tile.waterfall_graph) { 26985 tile.waterfall_graph.updateData(graphProps); 26986 return; 26987 } else { 26988 tile.waterfall_graph = new ShortfallWaterfallGraph(graphProps); 26989 } 26990 }, 26991 init: KpiDashboard.initTileElement 26992 } 26993 ], 26994 filterOptions: [ 26995 { 26996 type: PROGRAM_ACTIVE, 26997 options: [SHOW_ALL, SHOW_ONLY_ACTIVE], 26998 default_option: SHOW_ALL 26999 } 27000 ] 27001 }; 27002 KpiDashboardTiles.FINANCE_SHORTFALL_WATERFALL.waterfall_graph = null; 27003} 27004 27005 27006; 27007////pf: javascript/stats/panels/ar.tiles.js 27008// eslint-disable-next-line no-redeclare, no-unused-vars 27009function initArTiles() { 27010 const { 27011 TILE_ELEMENT, 27012 FILTER_TIME_PERIOD, 27013 FILTER_TYPE, 27014 time_periods_lifetime_to_last30, 27015 time_periods_current_fiscal_to_next30 27016 } = KpiTypes; 27017 const { CURRENT_FISCAL_YEAR, LAST_30_DAYS } = FILTER_TIME_PERIOD; 27018 const { TIME_PERIOD } = FILTER_TYPE; 27019 const { AR_TABLE, DONUT, SORTABLE_STATS } = TILE_ELEMENT; 27020 27021 KpiDashboardTiles.FINANCE_PAYMENTS = { 27022 panel: KPI_PANEL.ar, 27023 selector: '#Revenue__Tile5', 27024 title: 'Payments', 27025 tooltip: 'Payment summaries by payment method.', 27026 permissionsRequired: ['finance-group', 'ordersAdmin', 'programAdmin'], 27027 canGroupByBrand: true, 27028 elements: [ 27029 { 27030 type: DONUT, 27031 useBrandToggle: true, 27032 selector: '#RevenueTile5__Donut', 27033 handleRequest: params => fetchPaymentsDonutData(params), 27034 handleResponse: (response, selector) => { 27035 new DonutChart({ 27036 selector, 27037 data: response.segments, 27038 options: { 27039 innerLabel: 'Total Paid', 27040 innerValue: response.total, 27041 subLabels: response.subLabels 27042 } 27043 }); 27044 }, 27045 init: KpiDashboard.initTileElement 27046 }, 27047 { 27048 type: SORTABLE_STATS, 27049 useBrandToggle: true, 27050 selector: '#RevenueTile5__ProgressStats', 27051 tooltip: 'Total & New Payments by a Filtered Period of Time.', 27052 title: 'Recent Payments', 27053 handleRequest: params => fetchRevenueProgressData(params), 27054 handleResponse: (response, selector) => { 27055 ProgressStat.createGroup({ 27056 selector, 27057 progressStats: response.stats 27058 });
27059 }, 27060 renderProps: { 27061 options: { 27062 restructuredOrder: true, 27063 useEndCapLayout: true 27064 } 27065 }, 27066 queryParams: { 27067 limit: 7, 27068 fromBudget: 100, 27069 showTopResults: true 27070 }, 27071 init: KpiDashboard.initTileElement 27072 } 27073 ], 27074 filterOptions: [ 27075 { 27076 type: TIME_PERIOD, 27077 options: time_periods_lifetime_to_last30, 27078 default_option: LAST_30_DAYS 27079 } 27080 ] 27081 }; 27082 27083 KpiDashboardTiles.FINANCE_COLLECTED_FEES = { 27084 panel: KPI_PANEL.ar, 27085 selector: '#Finance__CollectedFeesOverTime', 27086 title: 'Collected Fees Over Time', 27087 tooltip: 'Collected Fees by a filtered period of time.', 27088 permissionsRequired: ['finance-group', 'shopEnterCredits'], 27089 elements: [ 27090 { 27091 type: DONUT, 27092 selector: '#Finance__CollectedFeesOverTime__Donut', 27093 handleRequest: params => fetchCollectedFeesDonut(params), 27094 handleResponse: (response, selector) => { 27095 new DonutChart({ 27096 selector, 27097 data: response.segments, 27098 options: { 27099 innerLabel: 'Total Fees', 27100 innerValue: response.total, 27101 subLabels: response.subLabels 27102 } 27103 }); 27104 }, 27105 init: KpiDashboard.initTileElement 27106 } 27107 ], 27108 filterOptions: [ 27109 { 27110 type: TIME_PERIOD, 27111 options: time_periods_lifetime_to_last30, 27112 default_option: LAST_30_DAYS 27113 } 27114 ] 27115 }; 27116 27117 KpiDashboardTiles.FINANCE_PROJECTED_FEES = { 27118 panel: KPI_PANEL.ar, 27119 selector: '#Finance__ProjectedFeesOverTime', 27120 title: 'Projected Fees Over Time', 27121 tooltip: 'Anticipated Fees to be Collected.', 27122 permissionsRequired: ['finance-group', 'shopEnterCredits'], 27123 elements: [ 27124 { 27125 type: DONUT, 27126 selector: '#Finance__ProjectedFeesOverTime__Donut', 27127 handleRequest: params => 27128 KpiData().fetchData('/api/dashboard/donut/projected_fees', { 27129 ...params, 27130 affiliationIds: getAffiliationIds() 27131 }), 27132 handleResponse: (response, selector) => { 27133 new DonutChart({ 27134 selector, 27135 data: response.segments, 27136 options: { 27137 innerLabel: 'Total Fees', 27138 innerValue: response.total, 27139 subLabels: response.subLabels 27140 } 27141 }); 27142 }, 27143 init: KpiDashboard.initTileElement 27144 } 27145 ], 27146 filterOptions: [ 27147 { 27148 type: TIME_PERIOD, 27149 options: time_periods_current_fiscal_to_next30, 27150 default_option: CURRENT_FISCAL_YEAR 27151 } 27152 ] 27153 }; 27154 27155 KpiDashboardTiles.FINANCE_ACCOUNTS_RECEIVABLE = { 27156 panel: KPI_PANEL.ar, 27157 selector: '#Revenue__Tile8', 27158 title: 'Accounts Receivable', 27159 tooltip: 'Outstanding A/R and details.', 27160 permissionsRequired: ['finance-group'], 27161 canGroupByBrand: true, 27162 elements: [ 27163 { 27164 type: DONUT, 27165 useBrandToggle: true, 27166 selector: '#RevenueTile8__Donut', 27167 handleRequest: params => 27168 KpiData().fetchData('/api/dashboard/donut/AR', { 27169 ...params, 27170 affiliationIds: getAffiliationIds() 27171 }), 27172 handleResponse: (response, selector) => { 27173 new DonutChart({ 27174 selector, 27175 data: response.segments, 27176 options: { 27177 innerLabel: 'Total Due', 27178 innerValue: response.total, 27179 subLabels: response.subLabels 27180 } 27181 }); 27182 }, 27183 init: KpiDashboard.initTileElement 27184 }, 27185 { 27186 type: AR_TABLE, 27187 useBrandToggle: true, 27188 selector: '#RevenueTile8__ArProgramTable', 27189 handleRequest: params => 27190 KpiData().fetchData('/api/dashboard/table/AR', { 27191 ...params, 27192 affiliationIds: getAffiliationIds() 27193 }), 27194 handleResponse: (response, selector, params) => { 27195 const tile = KpiDashboardTiles.FINANCE_ACCOUNTS_RECEIVABLE; 27196 27197 const tableProps = { 27198 selector, 27199 data: response.stats, 27200 params 27201 }; 27202 27203 if (!tile.ar_table) { 27204 tile.ar_table = new ArProgramTable(tableProps); 27205 } else { 27206 tile.ar_table.updateData(tableProps); 27207 } 27208 }, 27209 init: KpiDashboard.initTileElement 27210 } 27211 ], 27212 filterOptions: [] 27213 }; 27214 KpiDashboardTiles.FINANCE_ACCOUNTS_RECEIVABLE.ar_table = null; 27215 27216 KpiDashboardTiles.FINANCE_ACCOUNTS_RECEIVABLE_AGING_SUMMARY = { 27217 panel: KPI_PANEL.ar, 27218 selector: '#Revenue__Tile9', 27219 title: 'Accounts Receivable Aging Summary', 27220 tooltip: 'High-Level A/R Summary', 27221 permissionsRequired: ['finance-group'], 27222 elements: [ 27223 { 27224 type: 'bands', 27225 selector: '#AgingSummaryChart', 27226 handleRequest: params => 27227 KpiData().fetchData('/api/dashboard/bargraph/AR', { 27228 ...params, 27229 affiliationIds: getAffiliationIds() 27230 }), 27231 handleResponse: (response, selector) => { 27232 AgingSummaryBands.createDataBands({ 27233 selector, 27234 data: response.stats, 27235 formattedTotal: response.totalLabel 27236 });
27237 }, 27238 init: KpiDashboard.initTileElement 27239 } 27240 ], 27241 filterOptions: [] 27242 }; 27243 27244 $(function () { 27245 // Layout gets adjusted for tile visibility per role 27246 let arLayoutAdjusted = false; 27247 onPanelOpen(KPI_PANEL.ar, () => { 27248 if (!arLayoutAdjusted) { 27249 KpiUtils.adjustLayoutForFewVisibleTiles('#kpi-ar-section', 4); 27250 arLayoutAdjusted = true; 27251 } 27252 }); 27253 }); 27254} 27255 27256 27257; 27258////pf: javascript/stats/panels/statistics.tiles.js 27259// eslint-disable-next-line no-redeclare, no-unused-vars 27260function initStatisticsTiles() { 27261 const { 27262 TILE_ELEMENT, 27263 FILTER_PROGRAM_TYPE, 27264 FILTER_TIME_PERIOD, 27265 FILTER_TYPE, 27266 time_periods_lifetime_to_last30, 27267 time_periods_current_fiscal_to_next30, 27268 program_types_all 27269 } = KpiTypes; 27270 const { ECON_UNIT, STACKED_BARS, DONUT, PROGRESS_STATS, SORTABLE_STATS } = TILE_ELEMENT; 27271 const { TIME_PERIOD, PROGRAM_TYPE } = FILTER_TYPE; 27272 const { CURRENT_FISCAL_YEAR, LAST_30_DAYS, LAST_DAY } = FILTER_TIME_PERIOD; 27273 const { ALL_PROGRAM_TYPES } = FILTER_PROGRAM_TYPE; 27274 27275 KpiDashboardTiles.STATISTICS_AVG_TEAM_SIZE = { 27276 panel: KPI_PANEL.statistics, 27277 selector: '#StatsUE__tile1', 27278 title: 'Avg. Team Size and count across Programs', 27279 tooltip: 'Average number of teams in a program and athletes per team.', 27280 permissionsRequired: ['programs-group'], 27281 elements: [ 27282 { 27283 type: ECON_UNIT, 27284 selector: '#StatsUETile1__EconomicUnits', 27285 handleRequest: params => 27286 KpiData().fetchData('/api/dashboard/tile/average_team_sizes', { 27287 ...params, 27288 affiliationIds: getAffiliationIds() 27289 }), 27290 handleResponse: (response, selector) => { 27291 EconomicUnit.createGroup({ 27292 selector, 27293 data: response.tiles 27294 }); 27295 }, 27296 queryParams: {}, 27297 init: KpiDashboard.initTileElement 27298 } 27299 ], 27300 filterOptions: [ 27301 { 27302 type: TIME_PERIOD, 27303 options: time_periods_lifetime_to_last30, 27304 default_option: LAST_30_DAYS 27305 }, 27306 ] 27307 }; 27308 27309 KpiDashboardTiles.STATISTICS_UPCOMING_EVENT_TOTALS = { 27310 panel: KPI_PANEL.statistics, 27311 selector: '#StatsUE__tile2', 27312 title: 'Upcoming Event Totals', 27313 tooltip: 'Summary of upcoming events by type.', 27314 permissionsRequired: ['programs-group', 'teamAdmin'], 27315 elements: [ 27316 { 27317 type: ECON_UNIT, 27318 selector: '#StatsUETile2__EconomicUnits', 27319 handleRequest: params => 27320 KpiData().fetchData('/api/dashboard/tile/upcoming_events', { 27321 ...params, 27322 affiliationIds: getAffiliationIds() 27323 }), 27324 handleResponse: (response, selector) => { 27325 EconomicUnit.createGroup({ 27326 selector, 27327 data: response.tiles 27328 }); 27329 }, 27330 queryParams: {}, 27331 init: KpiDashboard.initTileElement 27332 } 27333 ], 27334 filterOptions: [ 27335 { 27336 type: TIME_PERIOD, 27337 options: time_periods_lifetime_to_last30, 27338 default_option: CURRENT_FISCAL_YEAR 27339 } 27340 ] 27341 }; 27342 27343 KpiDashboardTiles.STATISTICS_PREVIOUSLY_REGISTERED_VS_NEW_ATHLETES = { 27344 panel: KPI_PANEL.statistics, 27345 selector: '#Stats__tile1', 27346 title: 'New vs Existing Customers', 27347 tooltip: 'Comparison of registrants to the brand vs. previously registered for a program.', 27348 permissionsRequired: ['programs-group'], 27349 elements: [ 27350 { 27351 type: DONUT, 27352 selector: '#StatsDonutTile1__Donut', 27353 handleRequest: params => 27354 KpiData().fetchData('/api/dashboard/donut/statistics_registrations', { 27355 ...params, 27356 affiliationIds: getAffiliationIds() 27357 }), 27358 handleResponse: (response, selector) => { 27359 new DonutChart({ 27360 selector, 27361 options: { 27362 innerLabel: 'Total Registrants', 27363 innerValue: response.total, 27364 subLabels: response.subLabels 27365 }, 27366 data: response.segments 27367 }); 27368 }, 27369 queryParams: { 27370 isTransactional: true 27371 }, 27372 init: KpiDashboard.initTileElement 27373 } 27374 ], 27375 filterOptions: [ 27376 { 27377 type: TIME_PERIOD, 27378 options: time_periods_lifetime_to_last30, 27379 default_option: CURRENT_FISCAL_YEAR 27380 }, 27381 { 27382 type: PROGRAM_TYPE, 27383 options: program_types_all, 27384 default_option: ALL_PROGRAM_TYPES 27385 } 27386 ] 27387 }; 27388 27389 KpiDashboardTiles.STATISTICS_TEAM_REGISTRATIONS = { 27390 panel: KPI_PANEL.statistics, 27391 selector: '#Stats__tile2', 27392 title: 'Team Registrations', 27393 tooltip: 'Team registration details with comparison of revenue to budget.', 27394 permissionsRequired: ['finance-group', 'programs-group', 'ordersAdmin'], 27395 canGroupByBrand: true, 27396 elements: [ 27397 { 27398 type: STACKED_BARS, 27399 selector: '#StatsTile2__StackedBarGraph', 27400 handleRequest: params => 27401 KpiData().fetchData('/api/dashboard/bargraph/registrations_breakdown', { 27402 ...params, 27403 affiliationIds: getAffiliationIds() 27404 }), 27405 handleResponse: (response, selector, params) => { 27406 let tile = KpiDashboardTiles.STATISTICS_TEAM_REGISTRATIONS; 27407 27408 const barGraphProps = { 27409 data: response.data, 27410 options: { 27411 ...response.options, 27412 useMonthsFormat: true, 27413 margin: { left: 46 } 27414 }, 27415 params 27416 }; 27417 27418 if (tile.stacked_bar_graph) { 27419 tile.stacked_bar_graph.updateData(barGraphProps); 27420 return; 27421 } else { 27422 tile.stacked_bar_graph = new StackedBarGraph2({ 27423 ...barGraphProps, 27424 selector 27425 });
27426 } 27427 }, 27428 queryParams: { 27429 isTeamRegistration: true 27430 }, 27431 init: KpiDashboard.initTileElement 27432 }, 27433 { 27434 type: PROGRESS_STATS, 27435 useBrandToggle: true, 27436 selector: '#StatsTile2__ProgressStats', 27437 handleRequest: params => 27438 KpiData().fetchData('/api/dashboard/progress/registrations_breakdown', { 27439 ...params, 27440 affiliationIds: getAffiliationIds() 27441 }), 27442 handleResponse: (response, selector) => { 27443 ProgressStat.createGroup({ 27444 selector, 27445 progressStats: response.stats, 27446 title: 'Most Active Team-based Registrations', 27447 tooltip: 'Total & New Team Registration Numbers by a Filtered Period of Time.', 27448 options: { 27449 restructuredOrder: true, 27450 useEndCapLayout: true 27451 } 27452 }); 27453 }, 27454 queryParams: { 27455 isTeamRegistration: true 27456 }, 27457 init: KpiDashboard.initTileElement 27458 } 27459 ], 27460 filterOptions: [ 27461 { 27462 type: TIME_PERIOD, 27463 options: time_periods_lifetime_to_last30, 27464 default_option: CURRENT_FISCAL_YEAR 27465 } 27466 ] 27467 }; 27468 KpiDashboardTiles.STATISTICS_TEAM_REGISTRATIONS.stacked_bar_graph = null; 27469 27470 KpiDashboardTiles.STATISTICS_ATHLETE_REGISTRATIONS = { 27471 panel: KPI_PANEL.statistics, 27472 selector: '#Stats__tile3', 27473 title: 'Athlete Registrations', 27474 tooltip: 'Athlete registration details with comparison of revenue to budget.', 27475 permissionsRequired: ['finance-group', 'programs-group', 'ordersAdmin'], 27476 canGroupByBrand: true, 27477 elements: [ 27478 { 27479 type: STACKED_BARS, 27480 selector: '#StatsTile3__StackedBarGraph', 27481 handleRequest: params => 27482 KpiData().fetchData('/api/dashboard/bargraph/registrations_breakdown', { 27483 ...params, 27484 affiliationIds: getAffiliationIds() 27485 }), 27486 handleResponse: (response, selector, params) => { 27487 let tile = KpiDashboardTiles.STATISTICS_ATHLETE_REGISTRATIONS; 27488 27489 const barGraphProps = { 27490 data: response.data, 27491 options: { 27492 ...response.options, 27493 useMonthsFormat: true, 27494 margin: { left: 46 } 27495 }, 27496 params 27497 }; 27498 27499 if (tile.stacked_bar_graph) { 27500 tile.stacked_bar_graph.updateData(barGraphProps); 27501 return; 27502 } else { 27503 tile.stacked_bar_graph = new StackedBarGraph2({ 27504 ...barGraphProps, 27505 selector 27506 }); 27507 } 27508 }, 27509 queryParams: { 27510 isTeamRegistration: false 27511 }, 27512 init: KpiDashboard.initTileElement 27513 }, 27514 { 27515 type: PROGRESS_STATS, 27516 useBrandToggle: true, 27517 selector: '#StatsTile3__ProgressStats', 27518 handleRequest: params => fetchRegProgressStatData(params), 27519 handleResponse: (response, selector) => { 27520 ProgressStat.createGroup({ 27521 selector, 27522 title: 'Most Active Athlete-based Registrations', 27523 tooltip: 27524 'Total & New Individual Registration Numbers by a Filtered Period of Time.', 27525 progressStats: response.stats, 27526 options: { 27527 restructuredOrder: true, 27528 useEndCapLayout: true 27529 } 27530 }); 27531 }, 27532 queryParams: { 27533 isTeamRegistration: false 27534 }, 27535 init: KpiDashboard.initTileElement 27536 } 27537 ], 27538 filterOptions: [ 27539 { 27540 type: TIME_PERIOD, 27541 options: time_periods_lifetime_to_last30, 27542 default_option: CURRENT_FISCAL_YEAR 27543 } 27544 ] 27545 }; 27546 KpiDashboardTiles.STATISTICS_ATHLETE_REGISTRATIONS.stacked_bar_graph = null; 27547 27548 KpiDashboardTiles.STATISTICS_TOTAL_RUNNING_EVENTS = { 27549 panel: KPI_PANEL.statistics, 27550 selector: '#Stats__tile4A', 27551 title: 'Scheduled Events', 27552 tooltip: 'Events running or scheduled by event type.', 27553 permissionsRequired: ['programs-group', 'teamAdmin'], 27554 elements: [ 27555 { 27556 type: DONUT, 27557 selector: '#StatsDonutTile2__Donut', 27558 handleRequest: params => fetchStatsEventsDonut(params), 27559 handleResponse: (response, selector) => { 27560 new DonutChart({ 27561 selector, 27562 options: { 27563 innerLabel: 'Total Events', 27564 innerValue: response.total, 27565 subLabels: response.subLabels 27566 }, 27567 data: response.segments 27568 }); 27569 }, 27570 queryParams: { 27571 isTransactional: true 27572 }, 27573 init: KpiDashboard.initTileElement 27574 } 27575 ], 27576 filterOptions: [ 27577 { 27578 type: TIME_PERIOD, 27579 options: time_periods_lifetime_to_last30, 27580 default_option: CURRENT_FISCAL_YEAR 27581 }, 27582 { 27583 type: PROGRAM_TYPE, 27584 options: program_types_all, 27585 default_option: ALL_PROGRAM_TYPES 27586 } 27587 ] 27588 }; 27589 27590 KpiDashboardTiles.STATISTICS_PRACTICE_GAME_ATTENDANCE = { 27591 panel: KPI_PANEL.statistics, 27592 selector: '#Stats__tile5', 27593 title: 'Practice & game attendance Rate', 27594 tooltip: 'High level attendance vs practice summary.', 27595 permissionsRequired: ['programs-group', 'teamAdmin'], 27596 canGroupByBrand: true, 27597 elements: [ 27598 { 27599 type: SORTABLE_STATS, 27600 useBrandToggle: true, 27601 selector: '#StatsTile5__ProgressStats', 27602 handleRequest: params => 27603 KpiData().fetchData('/api/dashboard/progress/attendance', { 27604 ...params, 27605 affiliationIds: getAffiliationIds() 27606 }), 27607 handleResponse: (response, selector) => { 27608 ProgressStat.createGroup({ 27609 selector, 27610 progressStats: response.stats, 27611 options: { 27612 useEndCapLayout: true 27613 } 27614 });
27615 }, 27616 queryParams: { 27617 limit: 4, 27618 timePeriod: LAST_DAY 27619 }, 27620 init: KpiDashboard.initTileElement 27621 } 27622 ], 27623 filterOptions: [ 27624 { 27625 type: TIME_PERIOD, 27626 options: time_periods_lifetime_to_last30, 27627 default_option: LAST_30_DAYS 27628 } 27629 ] 27630 }; 27631 27632 KpiDashboardTiles.STATISTICS_EXPECTED_PLAYERS_BIG_EVENTS = { 27633 panel: KPI_PANEL.statistics, 27634 selector: '#Stats__tile6', 27635 title: 'Expected players for EVT', 27636 tooltip: 'Expected attendance of programs by EVT activity type.', 27637 permissionsRequired: ['programs-group'], 27638 elements: [ 27639 { 27640 type: STACKED_BARS, 27641 selector: '#StatsTile6__StackedBarGraph', 27642 handleRequest: params => fetchBigEventBarData(params), 27643 handleResponse: (response, selector, params) => { 27644 let tile = KpiDashboardTiles.STATISTICS_EXPECTED_PLAYERS_BIG_EVENTS; 27645 27646 const barGraphProps = { 27647 data: response.data, 27648 options: { 27649 ...response.options, 27650 useSmallLabels: true 27651 }, 27652 params 27653 }; 27654 27655 if (tile.stacked_bar_graph) { 27656 tile.stacked_bar_graph.updateData(barGraphProps); 27657 return; 27658 } 27659 27660 tile.stacked_bar_graph = new StackedBarGraph2({ 27661 ...barGraphProps, 27662 selector 27663 }); 27664 }, 27665 queryParams: {}, 27666 init: KpiDashboard.initTileElement 27667 } 27668 ], 27669 filterOptions: [ 27670 { 27671 type: TIME_PERIOD, 27672 options: time_periods_current_fiscal_to_next30, 27673 default_option: CURRENT_FISCAL_YEAR 27674 } 27675 ] 27676 }; 27677 KpiDashboardTiles.STATISTICS_EXPECTED_PLAYERS_BIG_EVENTS.stacked_bar_graph = null; 27678 27679 $(function () { 27680 // Layout gets adjusted for tile visibility per role 27681 let statsLayoutAdjusted = false; 27682 onPanelOpen(KPI_PANEL.statistics, () => { 27683 if (!statsLayoutAdjusted) { 27684 KpiUtils.adjustLayoutForFewVisibleTiles('#kpi-statistics-page .grid-container', 2); 27685 statsLayoutAdjusted = true; 27686 } 27687 }); 27688 }); 27689} 27690 27691 27692; 27693////pf: javascript/stats/panels/marketing.tiles.js 27694// eslint-disable-next-line no-redeclare, no-unused-vars 27695function initMarketingTiles() { 27696 const { 27697 TILE_ELEMENT, 27698 FILTER_TIME_PERIOD, 27699 FILTER_TYPE, 27700 time_periods_lifetime_to_last30, 27701 time_periods_last30_to_last7 27702 } = KpiTypes; 27703 const { CURRENT_FISCAL_YEAR, LAST_30_DAYS } = FILTER_TIME_PERIOD; 27704 const { TIME_PERIOD } = FILTER_TYPE; 27705 const { MULTILINE, DONUT, SORTABLE_STATS } = TILE_ELEMENT; 27706 27707 KpiDashboardTiles.MARKETING_EMAILS = { 27708 panel: KPI_PANEL.marketing, 27709 selector: '#Marketing__Tile1', 27710 title: 'Marketing Emails', 27711 tooltip: 'Total marketing emails sent and opened within a filtered period of time, listed by program. If multiple programs were tagged to the same email, the total recipients across all related programs will be reflected in each line below.', 27712 permissionsRequired: ['communications-group'], 27713 canGroupByBrand: true, 27714 elements: [ 27715 { 27716 type: DONUT, 27717 useBrandToggle: true, 27718 selector: '#MarketingTile1_Donut', 27719 handleRequest: params => fetchMarketingEmailsDonutData(params), 27720 handleResponse: (response, selector) => { 27721 new DonutChart({ 27722 selector, 27723 options: { 27724 innerLabel: 'Open Rate', 27725 innerValue: response.total, 27726 subLabels: response.subLabels, 27727 palette: DonutChart.palette.byPercent 27728 }, 27729 data: response.segments 27730 }); 27731 }, 27732 queryParams: { 27733 percentageColors: true, 27734 isTransactional: false 27735 }, 27736 init: KpiDashboard.initTileElement 27737 }, 27738 { 27739 type: SORTABLE_STATS, 27740 useBrandToggle: true, 27741 selector: '#MarketingTile1_ProgressStats', 27742 title: 'Open Rate For Marketing Emails', 27743 tooltip: 'Total marketing emails sent & opened by a filtered period of time.', 27744 handleRequest: params => 27745 KpiData().fetchData('/api/dashboard/progress/emails', { 27746 ...params, 27747 affiliationIds: getAffiliationIds() 27748 }), 27749 handleResponse: () => {}, // SORTABLE_STATS initializd in initTileElement() 27750 queryParams: { 27751 isTransactional: false, 27752 limit: 4, 27753 timePeriod: KpiTypes.FILTER_TIME_PERIOD.LAST_DAY.value 27754 }, 27755 init: KpiDashboard.initTileElement 27756 } 27757 ], 27758 filterOptions: [ 27759 { 27760 type: TIME_PERIOD, 27761 options: time_periods_last30_to_last7, 27762 default_option: LAST_30_DAYS 27763 } 27764 ] 27765 }; 27766 27767 KpiDashboardTiles.MARKETING_EMAILS_OVER_TIME = { 27768 panel: KPI_PANEL.marketing, 27769 selector: '#Marketing__Tile2', 27770 title: 'Marketing Emails Over time',
27771 tooltip: 'Display cadence of marketing emails and details.', 27772 permissionsRequired: ['communications-group'], 27773 elements: [ 27774 { 27775 type: MULTILINE, 27776 selector: '#MarketingTile2_MultiLineGraph', 27777 handleRequest: params => bindEmailsLineGraph(params), 27778 handleResponse: function (response, selector, params) { 27779 let tile = KpiDashboardTiles.MARKETING_EMAILS_OVER_TIME; 27780 27781 const chartProps = { 27782 data: response.data, 27783 options: response.options, 27784 params 27785 }; 27786 if (tile.multiline) { 27787 tile.multiline.updateData(chartProps); 27788 } else { 27789 tile.multiline = new MultiLineGraph({ 27790 selector, 27791 ...chartProps 27792 }); 27793 } 27794 }, 27795 queryParams: { 27796 isTransactional: false 27797 }, 27798 init: KpiDashboard.initTileElement 27799 } 27800 ], 27801 filterOptions: [ 27802 { 27803 type: TIME_PERIOD, 27804 options: time_periods_lifetime_to_last30, 27805 default_option: CURRENT_FISCAL_YEAR 27806 } 27807 ] 27808 }; 27809 KpiDashboardTiles.MARKETING_EMAILS_OVER_TIME.muliline = null; 27810 27811 KpiDashboardTiles.MARKETING_TRANSACTIONAL_EMAILS = { 27812 panel: KPI_PANEL.marketing, 27813 selector: '#Marketing__Tile3', 27814 title: 'Transactional Emails', 27815 tooltip: 'Total transactional emails sent and opened within a filtered period of time, listed by program. If multiple programs were tagged to the same email, the total recipients across all related programs will be reflected in each line below.', 27816 permissionsRequired: ['communicationsAdmin'], 27817 canGroupByBrand: true, 27818 elements: [ 27819 { 27820 type: DONUT, 27821 useBrandToggle: true, 27822 selector: '#MarketingTile3_Donut', 27823 handleRequest: params => fetchTransactionalEmailsDonutData(params), 27824 handleResponse: (response, selector) => { 27825 new DonutChart({ 27826 selector, 27827 options: { 27828 innerLabel: 'Open Rate', 27829 innerValue: response.total, 27830 subLabels: response.subLabels, 27831 palette: DonutChart.palette.byPercent 27832 }, 27833 data: response.segments 27834 }); 27835 }, 27836 queryParams: { 27837 percentageColors: true, 27838 isTransactional: true 27839 }, 27840 init: KpiDashboard.initTileElement 27841 }, 27842 { 27843 type: SORTABLE_STATS, 27844 useBrandToggle: true, 27845 selector: '#MarketingTile3_ProgressStats', 27846 title: 'Open Rate For Transactional Emails', 27847 tooltip: 'Total transactional emails sent & opened by a filtered period of time.', 27848 handleRequest: params => 27849 KpiData().fetchData('/api/dashboard/progress/emails', { 27850 ...params, 27851 affiliationIds: getAffiliationIds() 27852 }), 27853 handleResponse: () => {}, // SORTABLE_STATS initializd in initTileElement() 27854 queryParams: { 27855 isTransactional: true, 27856 limit: 4, 27857 timePeriod: LAST_30_DAYS 27858 }, 27859 init: KpiDashboard.initTileElement 27860 } 27861 ], 27862 filterOptions: [ 27863 { 27864 type: TIME_PERIOD, 27865 options: time_periods_last30_to_last7, 27866 default_option: LAST_30_DAYS 27867 } 27868 ] 27869 }; 27870 27871 KpiDashboardTiles.MARKETING_TRANSACTIONAL_EMAILS_OVER_TIME = { 27872 panel: KPI_PANEL.marketing, 27873 selector: '#Marketing__Tile4', 27874 title: 'Transactional Emails Over Time', 27875 tooltip: 'Display cadence of transactional emails and details.', 27876 permissionsRequired: ['communicationsAdmin'], 27877 elements: [ 27878 { 27879 type: MULTILINE, 27880 selector: '#MarketingTile4_MultiLineGraph', 27881 handleRequest: params => bindEmailsLineGraph(params), 27882 handleResponse: function (response, selector, params) { 27883 let tile = KpiDashboardTiles.MARKETING_TRANSACTIONAL_EMAILS_OVER_TIME; 27884 27885 const chartProps = { 27886 data: response.data, 27887 options: response.options, 27888 params 27889 }; 27890 if (tile.multiline) { 27891 tile.multiline.updateData(chartProps); 27892 return; 27893 } 27894 tile.multiline = new MultiLineGraph({ 27895 selector, 27896 ...chartProps 27897 }); 27898 }, 27899 queryParams: { 27900 isTransactional: true 27901 }, 27902 init: KpiDashboard.initTileElement 27903 } 27904 ], 27905 filterOptions: [ 27906 { 27907 type: TIME_PERIOD, 27908 options: time_periods_lifetime_to_last30, 27909 default_option: CURRENT_FISCAL_YEAR 27910 } 27911 ] 27912 }; 27913 KpiDashboardTiles.MARKETING_TRANSACTIONAL_EMAILS_OVER_TIME.muliline = null; 27914 27915 KpiDashboardTiles.MARKETING_COMMUNICATION_TYPE = { 27916 panel: KPI_PANEL.marketing, 27917 selector: '#Marketing__CommunicationType', 27918 title: 'Communication Type', 27919 tooltip: 'Communication Type by Numbers.', 27920 permissionsRequired: ['communicationsAdmin'], 27921 elements: [ 27922 { 27923 type: DONUT, 27924 selector: '#Marketing__CommunicationType__Donut', 27925 handleRequest: params => fetchEmailTypeDonutData(params), 27926 handleResponse: (response, selector) => { 27927 new DonutChart({ 27928 selector, 27929 options: {
27930 innerLabel: 'Total Sent', 27931 innerValue: response.total, 27932 subLabels: response.subLabels 27933 }, 27934 data: response.segments 27935 }); 27936 }, 27937 queryParams: {}, 27938 init: KpiDashboard.initTileElement 27939 } 27940 ], 27941 filterOptions: [ 27942 { 27943 type: TIME_PERIOD, 27944 options: time_periods_last30_to_last7, 27945 default_option: LAST_30_DAYS 27946 } 27947 ] 27948 }; 27949 27950 KpiDashboardTiles.MARKETING_COMMUNICATIONS_OVER_TIME = { 27951 panel: KPI_PANEL.marketing, 27952 selector: '#Marketing__SMSCommOverTime', 27953 title: 'SMS Communications Over Time', 27954 tooltip: 'Display cadence of SMS and its details.', 27955 permissionsRequired: ['communicationsAdmin'], 27956 elements: [ 27957 { 27958 type: MULTILINE, 27959 selector: '#Marketing__SMSCommOverTime__Line', 27960 handleRequest: params => 27961 KpiData().fetchData('/api/dashboard/linegraph/sms', { 27962 ...params, 27963 affiliationIds: getAffiliationIds() 27964 }), 27965 handleResponse: function (response, selector, params) { 27966 let tile = KpiDashboardTiles.MARKETING_COMMUNICATIONS_OVER_TIME; 27967 27968 const chartProps = { 27969 data: response.data, 27970 options: response.options, 27971 params 27972 }; 27973 if (tile.multiline) { 27974 tile.multiline.updateData(chartProps); 27975 return; 27976 } 27977 tile.multiline = new MultiLineGraph({ 27978 selector, 27979 ...chartProps 27980 }); 27981 }, 27982 init: KpiDashboard.initTileElement 27983 } 27984 ], 27985 filterOptions: [ 27986 { 27987 type: TIME_PERIOD, 27988 options: time_periods_lifetime_to_last30, 27989 default_option: CURRENT_FISCAL_YEAR 27990 } 27991 ] 27992 }; 27993 KpiDashboardTiles.MARKETING_COMMUNICATIONS_OVER_TIME.multiline = null; 27994 27995 // // TODO: Unload 27996 // const tiles = [ 27997 // KpiDashboardTiles.MARKETING_EMAILS, 27998 // KpiDashboardTiles.MARKETING_EMAILS_OVER_TIME, 27999 // KpiDashboardTiles.MARKETING_TRANSACTIONAL_EMAILS, 28000 // KpiDashboardTiles.MARKETING_TRANSACTIONAL_EMAILS_OVER_TIME, 28001 // KpiDashboardTiles.MARKETING_COMMUNICATION_TYPE, 28002 // KpiDashboardTiles.MARKETING_COMMUNICATIONS_OVER_TIME 28003 // ]; 28004 28005 $(function () { 28006 // Layout gets adjusted for tile visibility per role 28007 let marketingLayoutAdjusted = false; 28008 onPanelOpen(KPI_PANEL.marketing, () => { 28009 if (!marketingLayoutAdjusted) { 28010 KpiUtils.adjustLayoutForFewVisibleTiles('#kpi-marketing-page', 2); 28011 marketingLayoutAdjusted = true; 28012 } 28013 }); 28014 }); 28015} 28016 28017 28018; 28019////pf: javascript/stats/radial-gauge-2.js 28020$.fn.radialProgress2 = function (options) { 28021 $(this).each(function () { 28022 // prettier-ignore 28023 let { 28024 radius, 28025 color, 28026 backgroundColor, 28027 maxValue, 28028 minValue, 28029 value, 28030 strokeWidth, 28031 formattedValue, 28032 icon, 28033 offsetLabelY 28034 } = $.extend( 28035 { 28036 radius: 18, 28037 color: '#090', 28038 backgroundColor: '#BBB', 28039 maxValue: 100, 28040 minValue: 0, 28041 value: 0, 28042 strokeWidth: 8, 28043 formattedValue: null, 28044 icon: null, 28045 offsetLabelY: 0 28046 }, 28047 options 28048 ); 28049 28050 const fraction = Math.max(0, value / (2 * (maxValue - minValue))); 28051 28052 radius = Number(radius); 28053 strokeWidth = Number(strokeWidth); 28054 28055 const svgRadius = radius - strokeWidth / 2; 28056 28057 const getArc = ({ color, fraction, fractionOffset }) => { 28058 // prettier-ignore 28059 return `<path class="pie-gauge-arc" 28060 d="${ 28061 $.describeArc( 28062 radius, 28063 radius, 28064 svgRadius, 28065 (fractionOffset * 360) - 90, 28066 ((fractionOffset + fraction) * 360) - 90 28067 ) 28068 }" 28069 style="stroke:${color}; stroke-width: ${strokeWidth.toFixed(4)}px; fill: transparent;" > 28070 </path>`; 28071 }; 28072 28073 const safeFraction = Math.min(1, fraction); // clamp between 0 and 1 28074 28075 // if value is 0 or greater than 100 minus the spacer constant, don't show the spacer 28076 const SPACER_CONSTANT = 0.008; 28077 const spacerWidth = value == 0 || value >= 100 - SPACER_CONSTANT ? 0 : SPACER_CONSTANT; 28078 28079 const backgroundFraction = 1 - safeFraction - spacerWidth; 28080 const backgroundOffset = safeFraction + spacerWidth; 28081 28082 const arcs = [ 28083 // arc for the value 28084 getArc({ 28085 color: color, 28086 fraction: safeFraction, 28087 fractionOffset: 0, 28088 strokeWidth, 28089 }), 28090 // spacer between the two arcs 28091 getArc({ 28092 color: "#FFFFFF", 28093 fraction: spacerWidth, 28094 fractionOffset: safeFraction, 28095 strokeWidth, 28096 }), 28097 // arc for the background 28098 getArc({ 28099 color: backgroundColor, 28100 fraction: backgroundFraction, 28101 fractionOffset: backgroundOffset, 28102 strokeWidth, 28103 }), 28104 ]; 28105 28106 // prettier-ignore 28107 const svg = ` 28108 <div class="radial-progress-gauge" style="font-size: 1rem; width: ${radius * 2}px; height: ${radius.toFixed(4)}px;"> 28109 <svg viewPort="0 0 100 100" style="width: ${radius * 2}; height: 100%;" version="1.1" xmlns="http://www.w3.org/2000/svg">
28110 ${arcs.join('\n')} 28111 <text class='radial-progress-gauge-label' x="${radius}px" y="${radius - offsetLabelY - 1}px"> 28112 ${formattedValue || (fraction * 100).toFixed(0) + '%'} 28113 </text> 28114 </svg> 28115 </div> 28116 `; 28117 28118 $(this) 28119 .parent() 28120 .css('width', `${radius * 2}px`); 28121 $(this).append(svg); 28122 28123 // add an icon if specified 28124 if (icon != null) { 28125 const $icon = $(`<div class="radial-progress-2-icon"><i class="${icon}"></i></div>`); 28126 $icon.css('transform', `translate(${strokeWidth / 3}px, ${radius - 18}px)`); 28127 $(this).prepend($icon); 28128 } 28129 }); 28130 28131 return this; 28132}; 28133 28134// eslint-disable-next-line no-redeclare 28135const RadialGauge2 = {}; 28136 28137/** 28138 * Initialize a single radial gauge 28139 * 28140 * @param {HTMLElement} gauge - Element with the attribute [radial-progress-2] 28141 */ 28142RadialGauge2.initGauge = gauge => { 28143 // don't initialize if already initialized 28144 if (gauge.hasClass('radial-initialized')) return; 28145 28146 gauge.radialProgress2({ 28147 radius: gauge.attr('radius'), 28148 color: gauge.attr('color'), 28149 backgroundColor: gauge.attr('background-color'), 28150 maxValue: gauge.attr('max-value'), 28151 minValue: gauge.attr('min-value'), 28152 value: gauge.attr('value'), 28153 strokeWidth: gauge.attr('stroke-width'), 28154 formattedValue: gauge.attr('formatted-value'), 28155 icon: gauge.attr('icon'), 28156 offsetLabelY: gauge.attr('offset-label-y') 28157 }); 28158 28159 // add class so it doesn't get initialized again 28160 gauge.addClass('radial-initialized'); 28161}; 28162 28163/** 28164 * Initialize all radial gauges 28165 */ 28166RadialGauge2.init = () => { 28167 $('[radial-progress-2]').each(function () { 28168 RadialGauge2.initGauge($(this)); 28169 }); 28170}; 28171 28172/** 28173 * Alternative way of initializing radial gauges. 28174 * Creates the HTML element that is then initialized by RadialGauge2.init() or RadialGauge2.initGauge() 28175 * 28176 * @param {object} props 28177 * @param {string} props.title 28178 * @param {string} props.subtitle 28179 * @param {string} props.containerClasses 28180 * @param {string} props.backgroundColor 28181 * @param {number} props.radius 28182 * @param {number} props.value 28183 * @param {string} props.color 28184 * @param {number} props.strokeWidth 28185 * @param {string} props.formattedValue 28186 * @param {string} props.icon 28187 * 28188 * @returns {object} - Object with render() and html properties 28189 * @returns {function} render - Renders the gauge to the DOM 28190 * @returns {jQuery} html - jQuery object of the gauge 28191 */ 28192const $RadialGauge = props => { 28193 let html = null; 28194 28195 const init = () => { 28196 // description is optional, but it includes the title and subtitle 28197 let description = ''; 28198 if (props.title || props.subtitle) { 28199 description = ` 28200 <div class="gauge-description"> 28201 ${props.title ? `<div class="gauge-title">${props.title}</div>` : ''} 28202 ${props.subtitle ? `<div class="gauge-subtitle">${props.subtitle}</div>` : ''} 28203 </div> 28204 `; 28205 } 28206 28207 if (props.containerClasses && props.containerClasses.includes('disabled-widget')) { 28208 props.backgroundColor = '#E2E2E2'; 28209 } 28210 28211 html = $(` 28212 <div class="radial-progress-2 ${props.containerClasses}"> 28213 <div 28214 radial-progress-2 28215 radius="${props.radius || 60}" 28216 value="${props.value || 0}" 28217 color="${props.color || KpiUtils.colors.primary}" 28218 background-color="${props.backgroundColor || '#BBB'}" 28219 stroke-width="${props.strokeWidth || 20}" 28220 formatted-value="${props.formattedValue || 0}" 28221 offset-label-y="${props.offsetLabelY || 0}" 28222 ${props.icon && `icon=${props.icon}`}> 28223 </div> 28224 ${description} 28225 </div> 28226 `); 28227 return html; 28228 }; 28229 28230 const render = () => { 28231 $(props.containerSelector).append(html); 28232 }; 28233 28234 init(); 28235 28236 return { 28237 render, 28238 html 28239 }; 28240}; 28241 28242/** 28243 * Create a radial gauge for the retention list. 28244 * 28245 * @param {object} props - Ordinary radial gauge properties 28246 * @param {string} props.containerSelector - Selector of the container to render the gauge in (required) 28247 * @param {string} props.formattedValue - Value to display in the center of the gauge 28248 * @param {string} props.backgroundColor - Background color of the gauge 28249 * 28250 * @returns {object} - Object with render() and html properties 28251 * @returns {function} render - Renders the gauge to the DOM 28252 * @returns {jQuery} html - jQuery object of the gauge 28253 */ 28254const RetentionListRadial = function (props) { 28255 if (!props.containerSelector) return null; 28256 28257 const $container = $(props.containerSelector); 28258 28259 // remove any existing radial gauges 28260 if ($container.find('.radial-progress-2').length) { 28261 $container.find('.radial-progress-2').remove(); 28262 } 28263 28264 // set default values 28265 props.formattedValue = props.formattedValue || '--'; 28266 props.backgroundColor = props.formattedValue !== '--' ? '#BBB' : '#E2E2E2'; 28267 28268 const radialProps = { 28269 ...props, 28270 radius: 60, 28271 strokeWidth: 20, 28272 color: KpiUtils.colors.primary, 28273 offsetLabelY: 6 28274 // containerClasses: 'grayed-out' 28275 }; 28276 28277 const radial = $RadialGauge(radialProps); 28278 radial.render(); 28279 28280 RadialGauge2.initGauge($container.find('[radial-progress-2]')); 28281 return radial; 28282}; 28283 28284 28285; 28286////pf: node_modules/@googlemaps/markerclusterer/dist/index.min.js
vendor: 48,484 bytes, lines 28287-28288
28287var markerClusterer=function(t){"use strict";var r,e,n="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},o={};function i(){if(e)return r;e=1;var t=function(t){return t&&t.Math===Math&&t};return r=t("object"==typeof globalThis&&globalThis)||t("object"==typeof window&&window)||t("object"==typeof self&&self)||t("object"==typeof n&&n)||t("object"==typeof r&&r)||function(){return this}()||Function("return this")()}var s,a,u,c,f,l,h,p,m={};function d(){return a?s:(a=1,s=function(t){try{return!!t()}catch(t){return!0}})}function g(){if(c)return u;c=1;var t=d();return u=!t(function(){return 7!==Object.defineProperty({},1,{get:function(){return 7}})[1]})}function v(){if(l)return f;l=1;var t=d();return f=!t(function(){var t=function(){}.bind();return"function"!=typeof t||t.hasOwnProperty("prototype")})}function y(){if(p)return h;p=1;var t=v(),r=Function.prototype.call;return h=t?r.bind(r):function(){return r.apply(r,arguments)},h}var w,b,E,k,x,M,O,P,C,S,j,A,I,_,T,L,q,R,Z,z,D,F,N,U,B,W,$,V,G,H,K,Y,X,J,Q,tt,rt,et,nt,ot,it,st={};function at(){return E?b:(E=1,b=function(t,r){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:r}})}function ut(){if(x)return k;x=1;var t=v(),r=Function.prototype,e=r.call,n=t&&r.bind.bind(e,e);return k=t?n:function(t){return function(){return e.apply(t,arguments)}},k}function ct(){if(O)return M;O=1;var t=ut(),r=t({}.toString),e=t("".slice);return M=function(t){return e(r(t),8,-1)}}function ft(){return j?S:(j=1,S=function(t){return null==t})}function lt(){if(I)return A;I=1;var t=ft(),r=TypeError;return A=function(e){if(t(e))throw new r("Can't call method on "+e);return e}}function ht(){if(T)return _;T=1;var t=function(){if(C)return P;C=1;var t=ut(),r=d(),e=ct(),n=Object,o=t("".split);return P=r(function(){return!n("z").propertyIsEnumerable(0)})?function(t){return"String"===e(t)?o(t,""):n(t)}:n}(),r=lt();return _=function(e){return t(r(e))}}function pt(){if(q)return L;q=1;var t="object"==typeof document&&document.all;return L=void 0===t&&void 0!==t?function(r){return"function"==typeof r||r===t}:function(t){return"function"==typeof t}}function mt(){if(Z)return R;Z=1;var t=pt();return R=function(r){return"object"==typeof r?null!==r:t(r)}}function dt(){if(D)return z;D=1;var t=i(),r=pt();return z=function(e,n){return arguments.length<2?(o=t[e],r(o)?o:void 0):t[e]&&t[e][n];var o},z}function gt(){if(N)return F;N=1;var t=ut();return F=t({}.isPrototypeOf)}function vt(){if($)return W;$=1;var t,r,e=i(),n=function(){if(B)return U;B=1;var t=i().navigator,r=t&&t.userAgent;return U=r?String(r):""}(),o=e.process,s=e.Deno,a=o&&o.versions||s&&s.version,u=a&&a.v8;return u&&(r=(t=u.split("."))[0]>0&&t[0]<4?1:+(t[0]+t[1])),!r&&n&&(!(t=n.match(/Edge\/(\d+)/))||t[1]>=74)&&(t=n.match(/Chrome\/(\d+)/))&&(r=+t[1]),W=r}function yt(){if(G)return V;G=1;var t=vt(),r=d(),e=i().String;return V=!!Object.getOwnPropertySymbols&&!r(function(){var r=Symbol("symbol detection");return!e(r)||!(Object(r)instanceof Symbol)||!Symbol.sham&&t&&t<41})}function wt(){if(K)return H;K=1;var t=yt();return H=t&&!Symbol.sham&&"symbol"==typeof Symbol.iterator}function bt(){if(X)return Y;X=1;var t=dt(),r=pt(),e=gt(),n=wt(),o=Object;return Y=n?function(t){return"symbol"==typeof t}:function(n){var i=t("Symbol");return r(i)&&e(i.prototype,o(n))}}function Et(){if(Q)return J;Q=1;var t=String;return J=function(r){try{return t(r)}catch(t){return"Object"}}}function kt(){if(rt)return tt;rt=1;var t=pt(),r=Et(),e=TypeError;return tt=function(n){if(t(n))return n;throw new e(r(n)+" is not a function")}}function xt(){if(nt)return et;nt=1;var t=kt(),r=ft();return et=function(e,n){var o=e[n];return r(o)?void 0:t(o)}}function Mt(){if(it)return ot;it=1;var t=y(),r=pt(),e=mt(),n=TypeError;return ot=function(o,i){var s,a;if("string"===i&&r(s=o.toString)&&!e(a=t(s,o)))return a;if(r(s=o.valueOf)&&!e(a=t(s,o)))return a;if("string"!==i&&r(s=o.toString)&&!e(a=t(s,o)))return a;throw new n("Can't convert object to primitive value")}}var Ot,Pt,Ct,St,jt,At,It,_t,Tt,Lt,qt,Rt,Zt,zt,Dt,Ft,Nt,Ut,Bt,Wt,$t,Vt,Gt,Ht,Kt={exports:{}};function Yt(){return Pt?Ot:(Pt=1,Ot=!1)}function Xt(){if(St)return Ct;St=1;var t=i(),r=Object.defineProperty;return Ct=function(e,n){try{r(t,e,{value:n,configurable:!0,writable:!0})}catch(r){t[e]=n}return n}}function Jt(){if(jt)return Kt.exports;jt=1;var t=Yt(),r=i(),e=Xt(),n="__core-js_shared__",o=Kt.exports=r[n]||e(n,{});return(o.versions||(o.versions=[])).push({version:"3.44.0",mode:t?"pure":"global",copyright:"© 2014-2025 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.44.0/LICENSE",source:"https://github.com/zloirock/core-js"}),Kt.exports}function Qt(){if(It)return At;It=1;var t=Jt();return At=function(r,e){return t[r]||(t[r]=e||{})}}function tr(){if(Tt)return _t;Tt=1;var t=lt(),r=Object;return _t=function(e){return r(t(e))}}function rr(){if(qt)return Lt;qt=1;var t=ut(),r=tr(),e=t({}.hasOwnProperty);return Lt=Object.hasOwn||function(t,n){return e(r(t),n)}}function er(){if(Zt)return Rt;Zt=1;var t=ut(),r=0,e=Math.random(),n=t(1.1.toString);return Rt=function(t){return"Symbol("+(void 0===t?"":t)+")_"+n(++r+e,36)}}function nr(){if(Dt)return zt;Dt=1;var t=i(),r=Qt(),e=rr(),n=er(),o=yt(),s=wt(),a=t.Symbol,u=r("wks"),c=s?a.for||a:a&&a.withoutSetter||n;return zt=function(t){return e(u,t)||(u[t]=o&&e(a,t)?a[t]:c("Symbol."+t)),u[t]}}function or(){if(Nt)return Ft;Nt=1;var t=y(),r=mt(),e=bt(),n=xt(),o=Mt(),i=nr(),s=TypeError,a=i("toPrimitive");return Ft=function(i,u){if(!r(i)||e(i))return i;var c,f=n(i,a);if(f){if(void 0===u&&(u="default"),c=t(f,i,u),!r(c)||e(c))return c;throw new s("Can't convert object to primitive value")}return void 0===u&&(u="number"),o(i,u)}}function ir(){if(Bt)return Ut;Bt=1;var t=or(),r=bt();return Ut=function(e){var n=t(e,"string");return r(n)?n:n+""}}function sr(){if($t)return Wt;$t=1;var t=i(),r=mt(),e=t.document,n=r(e)&&r(e.createElement);return Wt=function(t){return n?e.createElement(t):{}}}function ar(){if(Gt)return Vt;Gt=1;var t=g(),r=d(),e=sr();return Vt=!t&&!r(function(){return 7!==Object.defineProperty(e("div"),"a",{get:function(){return 7}}).a})}function ur(){if(Ht)return m;Ht=1;var t=g(),r=y(),e=function(){if(w)return st;w=1;var t={}.propertyIsEnumerable,r=Object.getOwnPropertyDescriptor,e=r&&!t.call({1:2},1);return st.f=e?function(t){var e=r(this,t);return!!e&&e.enumerable}:t,st}(),n=at(),o=ht(),i=ir(),s=rr(),a=ar(),u=Object.getOwnPropertyDescriptor;return m.f=t?u:function(t,c){if(t=o(t),c=i(c),a)try{return u(t,c)}catch(t){}if(s(t,c))return n(!r(e.f,t,c),t[c])},m}var cr,fr,lr,hr,pr,mr,dr,gr={};function vr(){if(fr)return cr;fr=1;var t=g(),r=d();return cr=t&&r(function(){return 42!==Object.defineProperty(function(){},"prototype",{value:42,writable:!1}).prototype})}function yr(){if(hr)return lr;hr=1;var t=mt(),r=String,e=TypeError;return lr=function(n){if(t(n))return n;throw new e(r(n)+" is not an object")}}function wr(){if(pr)return gr;pr=1;var t=g(),r=ar(),e=vr(),n=yr(),o=ir(),i=TypeError,s=Object.defineProperty,a=Object.getOwnPropertyDescriptor,u="enumerable",c="configurable",f="writable";return gr.f=t?e?function(t,r,e){if(n(t),r=o(r),n(e),"function"==typeof t&&"prototype"===r&&"value"in e&&f in e&&!e[f]){var i=a(t,r);i&&i[f]&&(t[r]=e.value,e={configurable:c in e?e[c]:i[c],enumerable:u in e?e[u]:i[u],writable:!1})}return s(t,r,e)}:s:function(t,e,a){if(n(t),e=o(e),n(a),r)try{return s(t,e,a)}catch(t){}if("get"in a||"set"in a)throw new i("Accessors not supported");return"value"in a&&(t[e]=a.value),t},gr}function br(){if(dr)return mr;dr=1;var t=g(),r=wr(),e=at();return mr=t?function(t,n,o){return r.f(t,n,e(1,o))}:function(t,r,e){return t[r]=e,t}}var Er,kr,xr,Mr,Or,Pr,Cr,Sr,jr,Ar,Ir,_r,Tr,Lr,qr,Rr={exports:{}};function Zr(){if(Mr)return xr;Mr=1;var t=ut(),r=pt(),e=Jt(),n=t(Function.toString);return r(e.inspectSource)||(e.inspectSource=function(t){return n(t)}),xr=e.inspectSource}function zr(){if(Sr)return Cr;Sr=1;var t=Qt(),r=er(),e=t("keys");return Cr=function(t){return e[t]||(e[t]=r(t))}}function Dr(){return Ar?jr:(Ar=1,jr={})}function Fr(){if(_r)return Ir;_r=1;var t,r,e,n=function(){if(Pr)return Or;Pr=1;var t=i(),r=pt(),e=t.WeakMap;return Or=r(e)&&/native code/.test(String(e))}(),o=i(),s=mt(),a=br(),u=rr(),c=Jt(),f=zr(),l=Dr(),h="Object already initialized",p=o.TypeError,m=o.WeakMap;if(n||c.state){var d=c.state||(c.state=new m);d.get=d.get,d.has=d.has,d.set=d.set,t=function(t,r){if(d.has(t))throw new p(h);return r.facade=t,d.set(t,r),r},r=function(t){return d.get(t)||{}},e=function(t){return d.has(t)}}else{var g=f("state");l[g]=!0,t=function(t,r){if(u(t,g))throw new p(h);return r.facade=t,a(t,g,r),r},r=function(t){return u(t,g)?t[g]:{}},e=function(t){return u(t,g)}}return Ir={set:t,get:r,has:e,enforce:function(n){return e(n)?r(n):t(n,{})},getterFor:function(t){return function(e){var n;if(!s(e)||(n=r(e)).type!==t)throw new p("Incompatible receiver, "+t+" required");return n}}}}function Nr(){if(Tr)return Rr.exports;Tr=1;var t=ut(),r=d(),e=pt(),n=rr(),o=g(),i=function(){if(kr)return Er;kr=1;var t=g(),r=rr(),e=Function.prototype,n=t&&Object.getOwnPropertyDescriptor,o=r(e,"name"),i=o&&"something"===function(){}.name,s=o&&(!t||t&&n(e,"name").configurable);return Er={EXISTS:o,PROPER:i,CONFIGURABLE:s}}().CONFIGURABLE,s=Zr(),a=Fr(),u=a.enforce,c=a.get,f=String,l=Object.defineProperty,h=t("".slice),p=t("".replace),m=t([].join),v=o&&!r(function(){return 8!==l(function(){},"length",{value:8}).length}),y=String(String).split("String"),w=Rr.exports=function(t,r,e){"Symbol("===h(f(r),0,7)&&(r="["+p(f(r),/^Symbol\(([^)]*)\).*$/,"$1")+"]"),e&&e.getter&&(r="get "+r),e&&e.setter&&(r="set "+r),(!n(t,"name")||i&&t.name!==r)&&(o?l(t,"name",{value:r,configurable:!0}):t.name=r),v&&e&&n(e,"arity")&&t.length!==e.arity&&l(t,"length",{value:e.arity});try{e&&n(e,"constructor")&&e.constructor?o&&l(t,"prototype",{writable:!1}):t.prototype&&(t.prototype=void 0)}catch(t){}var s=u(t);return n(s,"source")||(s.source=m(y,"string"==typeof r?r:"")),t};return Function.prototype.toString=w(function(){return e(this)&&c(this).source||s(this)},"toString"),Rr.exports}function Ur(){if(qr)return Lr;qr=1;var t=pt(),r=wr(),e=Nr(),n=Xt();return Lr=function(o,i,s,a){a||(a={});var u=a.enumerable,c=void 0!==a.name?a.name:i;if(t(s)&&e(s,c,a),a.global)u?o[i]=s:n(i,s);else{try{a.unsafe?o[i]&&(u=!0):delete o[i]}catch(t){}u?o[i]=s:r.f(o,i,{value:s,enumerable:!1,configurable:!a.nonConfigurable,writable:!a.nonWritable})}return o}}var Br,Wr,$r,Vr,Gr,Hr,Kr,Yr,Xr,Jr,Qr,te,re,ee,ne,oe,ie,se={};function ae(){if(Vr)return $r;Vr=1;var t=function(){if(Wr)return Br;Wr=1;var t=Math.ceil,r=Math.floor;return Br=Math.trunc||function(e){var n=+e;return(n>0?r:t)(n)}}();return $r=function(r){var e=+r;return e!=e||0===e?0:t(e)}}function ue(){if(Hr)return Gr;Hr=1;var t=ae(),r=Math.max,e=Math.min;return Gr=function(n,o){var i=t(n);return i<0?r(i+o,0):e(i,o)}}function ce(){if(Yr)return Kr;Yr=1;var t=ae(),r=Math.min;return Kr=function(e){var n=t(e);return n>0?r(n,9007199254740991):0}}function fe(){if(Jr)return Xr;Jr=1;var t=ce();return Xr=function(r){return t(r.length)}}function le(){if(ee)return re;ee=1;var t=ut(),r=rr(),e=ht(),n=function(){if(te)return Qr;te=1;var t=ht(),r=ue(),e=fe(),n=function(n){return function(o,i,s){var a=t(o),u=e(a);if(0===u)return!n&&-1;var c,f=r(s,u);if(n&&i!=i){for(;u>f;)if((c=a[f++])!=c)return!0}else for(;u>f;f++)if((n||f in a)&&a[f]===i)return n||f||0;return!n&&-1}};return Qr={includes:n(!0),indexOf:n(!1)}}().indexOf,o=Dr(),i=t([].push);return re=function(t,s){var a,u=e(t),c=0,f=[];for(a in u)!r(o,a)&&r(u,a)&&i(f,a);for(;s.length>c;)r(u,a=s[c++])&&(~n(f,a)||i(f,a));return f}}function he(){return oe?ne:(oe=1,ne=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"])}var pe,me,de,ge,ve,ye,we,be,Ee,ke,xe,Me,Oe,Pe,Ce,Se,je,Ae,Ie,_e={};function Te(){if(de)return me;de=1;var t=dt(),r=ut(),e=function(){if(ie)return se;ie=1;var t=le(),r=he().concat("length","prototype");return se.f=Object.getOwnPropertyNames||function(e){return t(e,r)},se}(),n=(pe||(pe=1,_e.f=Object.getOwnPropertySymbols),_e),o=yr(),i=r([].concat);return me=t("Reflect","ownKeys")||function(t){var r=e.f(o(t)),s=n.f;return s?i(r,s(t)):r},me}function Le(){if(ve)return ge;ve=1;var t=rr(),r=Te(),e=ur(),n=wr();return ge=function(o,i,s){for(var a=r(i),u=n.f,c=e.f,f=0;f<a.length;f++){var l=a[f];t(o,l)||s&&t(s,l)||u(o,l,c(i,l))}},ge}function qe(){if(Ee)return be;Ee=1;var t=i(),r=ur().f,e=br(),n=Ur(),o=Xt(),s=Le(),a=function(){if(we)return ye;we=1;var t=d(),r=pt(),e=/#|\.prototype\./,n=function(e,n){var u=i[o(e)];return u===a||u!==s&&(r(n)?t(n):!!n)},o=n.normalize=function(t){return String(t).replace(e,".").toLowerCase()},i=n.data={},s=n.NATIVE="N",a=n.POLYFILL="P";return ye=n}();return be=function(i,u){var c,f,l,h,p,m=i.target,d=i.global,g=i.stat;if(c=d?t:g?t[m]||o(m,{}):t[m]&&t[m].prototype)for(f in u){if(h=u[f],l=i.dontCallGetSet?(p=r(c,f))&&p.value:c[f],!a(d?f:m+(g?".":"#")+f,i.forced)&&void 0!==l){if(typeof h==typeof l)continue;s(h,l)}(i.sham||l&&l.sham)&&e(h,"sham",!0),n(c,f,h,i)}}}function Re(){if(xe)return ke;xe=1;var t=gt(),r=TypeError;return ke=function(e,n){if(t(n,e))return e;throw new r("Incorrect invocation")}}function Ze(){if(Ce)return Pe;Ce=1;var t=rr(),r=pt(),e=tr(),n=zr(),o=function(){if(Oe)return Me;Oe=1;var t=d();return Me=!t(function(){function t(){}return t.prototype.constructor=null,Object.getPrototypeOf(new t)!==t.prototype})}(),i=n("IE_PROTO"),s=Object,a=s.prototype;return Pe=o?s.getPrototypeOf:function(n){var o=e(n);if(t(o,i))return o[i];var u=o.constructor;return r(u)&&o instanceof u?u.prototype:o instanceof s?a:null}}function ze(){if(je)return Se;je=1;var t=Nr(),r=wr();return Se=function(e,n,o){return o.get&&t(o.get,n,{getter:!0}),o.set&&t(o.set,n,{setter:!0}),r.f(e,n,o)}}function De(){if(Ie)return Ae;Ie=1;var t=g(),r=wr(),e=at();return Ae=function(n,o,i){t?r.f(n,o,e(0,i)):n[o]=i}}var Fe,Ne,Ue,Be,We,$e,Ve,Ge,He,Ke,Ye,Xe={};function Je(){if(Ne)return Fe;Ne=1;var t=le(),r=he();return Fe=Object.keys||function(e){return t(e,r)}}function Qe(){if(We)return Be;We=1;var t=dt();return Be=t("document","documentElement")}function tn(){if(Ve)return $e;Ve=1;var t,r=yr(),e=function(){if(Ue)return Xe;Ue=1;var t=g(),r=vr(),e=wr(),n=yr(),o=ht(),i=Je();return Xe.f=t&&!r?Object.defineProperties:function(t,r){n(t);for(var s,a=o(r),u=i(r),c=u.length,f=0;c>f;)e.f(t,s=u[f++],a[s]);return t},Xe}(),n=he(),o=Dr(),i=Qe(),s=sr(),a=zr(),u="prototype",c="script",f=a("IE_PROTO"),l=function(){},h=function(t){return"<"+c+">"+t+"</"+c+">"},p=function(t){t.write(h("")),t.close();var r=t.parentWindow.Object;return t=null,r},m=function(){try{t=new ActiveXObject("htmlfile")}catch(t){}var r,e,o;m="undefined"!=typeof document?document.domain&&t?p(t):(e=s("iframe"),o="java"+c+":",e.style.display="none",i.appendChild(e),e.src=String(o),(r=e.contentWindow.document).open(),r.write(h("document.F=Object")),r.close(),r.F):p(t);for(var a=n.length;a--;)delete m[u][n[a]];return m()};return o[f]=!0,$e=Object.create||function(t,n){var o;return null!==t?(l[u]=r(t),o=new l,l[u]=null,o[f]=t):o=m(),void 0===n?o:e.f(o,n)}}function rn(){if(He)return Ge;He=1;var t,r,e,n=d(),o=pt(),i=mt(),s=tn(),a=Ze(),u=Ur(),c=nr(),f=Yt(),l=c("iterator"),h=!1;return[].keys&&("next"in(e=[].keys())?(r=a(a(e)))!==Object.prototype&&(t=r):h=!0),!i(t)||n(function(){var r={};return t[l].call(r)!==r})?t={}:f&&(t=s(t)),o(t[l])||u(t,l,function(){return this}),Ge={IteratorPrototype:t,BUGGY_SAFARI_ITERATORS:h}}Ye||(Ye=1,function(){if(Ke)return o;Ke=1;var t=qe(),r=i(),e=Re(),n=yr(),s=pt(),a=Ze(),u=ze(),c=De(),f=d(),l=rr(),h=nr(),p=rn().IteratorPrototype,m=g(),v=Yt(),y="constructor",w="Iterator",b=h("toStringTag"),E=TypeError,k=r[w],x=v||!s(k)||k.prototype!==p||!f(function(){k({})}),M=function(){if(e(this,p),a(this)===p)throw new E("Abstract class Iterator not directly constructable")},O=function(t,r){m?u(p,t,{configurable:!0,get:function(){return r},set:function(r){if(n(this),this===p)throw new E("You can't redefine this property");l(this,t)?this[t]=r:c(this,t,r)}}):p[t]=r};l(p,b)||O(b,w),!x&&l(p,y)&&p[y]!==Object||O(y,M),M.prototype=p,t({global:!0,constructor:!0,forced:x},{Iterator:M})}());var en,nn,on,sn,an,un,cn,fn,ln,hn,pn,mn,dn,gn,vn,yn,wn,bn,En,kn,xn={};function Mn(){return nn?en:(nn=1,en=function(t){return{iterator:t,next:t.next,done:!1}})}function On(){if(sn)return on;sn=1;var t=Ur();return on=function(r,e,n){for(var o in e)t(r,o,e[o],n);return r}}function Pn(){return un?an:(un=1,an=function(t,r){return{value:t,done:r}})}function Cn(){if(fn)return cn;fn=1;var t=y(),r=yr(),e=xt();return cn=function(n,o,i){var s,a;r(n);try{if(!(s=e(n,"return"))){if("throw"===o)throw i;return i}s=t(s,n)}catch(t){a=!0,s=t}if("throw"===o)throw i;if(a)throw s;return r(s),i}}function Sn(){if(hn)return ln;hn=1;var t=Cn();return ln=function(r,e,n){for(var o=r.length-1;o>=0;o--)if(void 0!==r[o])try{n=t(r[o].iterator,e,n)}catch(t){e="throw",n=t}if("throw"===e)throw n;return n}}function jn(){if(mn)return pn;mn=1;var t=y(),r=tn(),e=br(),n=On(),o=nr(),i=Fr(),s=xt(),a=rn().IteratorPrototype,u=Pn(),c=Cn(),f=Sn(),l=o("toStringTag"),h="IteratorHelper",p="WrapForValidIterator",m="normal",d="throw",g=i.set,v=function(e){var o=i.getterFor(e?p:h);return n(r(a),{next:function(){var t=o(this);if(e)return t.nextHandler();if(t.done)return u(void 0,!0);try{var r=t.nextHandler();return t.returnHandlerResult?r:u(r,t.done)}catch(r){throw t.done=!0,r}},return:function(){var r=o(this),n=r.iterator;if(r.done=!0,e){var i=s(n,"return");return i?t(i,n):u(void 0,!0)}if(r.inner)try{c(r.inner.iterator,m)}catch(t){return c(n,d,t)}if(r.openIters)try{f(r.openIters,m)}catch(t){return c(n,d,t)}return n&&c(n,m),u(void 0,!0)}})},w=v(!0),b=v(!1);return e(b,l,"Iterator Helper"),pn=function(t,r,e){var n=function(n,o){o?(o.iterator=n.iterator,o.next=n.next):o=n,o.type=r?p:h,o.returnHandlerResult=!!e,o.nextHandler=t,o.counter=0,o.done=!1,g(this,o)};return n.prototype=r?w:b,n}}function An(){if(gn)return dn;gn=1;var t=yr(),r=Cn();return dn=function(e,n,o,i){try{return i?n(t(o)[0],o[1]):n(o)}catch(t){r(e,"throw",t)}}}function In(){return yn?vn:(yn=1,vn=function(t,r){var e="function"==typeof Iterator&&Iterator.prototype[t];if(e)try{e.call({next:null},r).next()}catch(t){return!0}})}function _n(){if(bn)return wn;bn=1;var t=i();return wn=function(r,e){var n=t.Iterator,o=n&&n.prototype,i=o&&o[r],s=!1;if(i)try{i.call({next:function(){return{done:!0}},return:function(){s=!0}},-1)}catch(t){t instanceof e||(s=!1)}if(!s)return i}}function Tn(t,r){var e={};for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&r.indexOf(n)<0&&(e[n]=t[n]);if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(n=Object.getOwnPropertySymbols(t);o<n.length;o++)r.indexOf(n[o])<0&&Object.prototype.propertyIsEnumerable.call(t,n[o])&&(e[n[o]]=t[n[o]])}return e}kn||(kn=1,function(){if(En)return xn;En=1;var t=qe(),r=y(),e=kt(),n=yr(),o=Mn(),i=jn(),s=An(),a=Cn(),u=In(),c=_n(),f=Yt(),l=!f&&!u("map",function(){}),h=!f&&!l&&c("map",TypeError),p=f||l||h,m=i(function(){var t=this.iterator,e=n(r(this.next,t));if(!(this.done=!!e.done))return s(t,this.mapper,[e.value,this.counter++],!0)});t({target:"Iterator",proto:!0,real:!0,forced:p},{map:function(t){n(this);try{e(t)}catch(t){a(this,"throw",t)}return h?r(h,this,t):new m(o(this),{mapper:t})}})}()),"function"==typeof SuppressedError&&SuppressedError;var Ln,qn,Rn={};qn||(qn=1,function(){if(Ln)return Rn;Ln=1;var t=qe(),r=y(),e=kt(),n=yr(),o=Mn(),i=jn(),s=An(),a=Yt(),u=Cn(),c=In(),f=_n(),l=!a&&!c("filter",function(){}),h=!a&&!l&&f("filter",TypeError),p=a||l||h,m=i(function(){for(var t,e,o=this.iterator,i=this.predicate,a=this.next;;){if(t=n(r(a,o)),this.done=!!t.done)return;if(e=t.value,s(o,i,[e,this.counter++],!0))return e}});t({target:"Iterator",proto:!0,real:!0,forced:p},{filter:function(t){n(this);try{e(t)}catch(t){u(this,"throw",t)}return h?r(h,this,t):new m(o(this),{predicate:t})}})}());class Zn{static isAdvancedMarkerAvailable(t){return google.maps.marker&&!0===t.getMapCapabilities().isAdvancedMarkersAvailable}static isAdvancedMarker(t){return google.maps.marker&&t instanceof google.maps.marker.AdvancedMarkerElement}static setMap(t,r){this.isAdvancedMarker(t)?t.map=r:t.setMap(r)}static getPosition(t){if(this.isAdvancedMarker(t)){if(t.position){if(t.position instanceof google.maps.LatLng)return t.position;if(Number.isFinite(t.position.lat)&&Number.isFinite(t.position.lng))return new google.maps.LatLng(t.position.lat,t.position.lng)}return new google.maps.LatLng(null)}return t.getPosition()}static getVisible(t){return!!this.isAdvancedMarker(t)||t.getVisible()}}class zn{constructor(t){let{markers:r,position:e}=t;this.markers=[],r&&(this.markers=r),e&&(e instanceof google.maps.LatLng?this._position=e:this._position=new google.maps.LatLng(e))}get bounds(){if(0===this.markers.length&&!this._position)return;const t=new google.maps.LatLngBounds(this._position,this._position);for(const r of this.markers)t.extend(Zn.getPosition(r));return t}get position(){return this._position||this.bounds.getCenter()}get count(){return this.markers.filter(t=>Zn.getVisible(t)).length}push(t){this.markers.push(t)}delete(){this.marker&&(Zn.setMap(this.marker,null),this.marker=void 0),this.markers.length=0}}function Dn(t){if(null==t)throw Error(arguments.length>1&&void 0!==arguments[1]?arguments[1]:"assertion failed")}const Fn=(t,r,e,n)=>{const o=t.getBounds();Dn(o);const i=Nn(o,r,n);return e.filter(t=>i.contains(Zn.getPosition(t)))},Nn=(t,r,e)=>{const{northEast:n,southWest:o}=Wn(t,r),i=$n({northEast:n,southWest:o},e);return Vn(i,r)},Un=(t,r,e)=>{const n=Nn(t,r,e),o=n.getNorthEast(),i=n.getSouthWest();return[i.lng(),i.lat(),o.lng(),o.lat()]},Bn=(t,r)=>{const e=(r.lat-t.lat)*Math.PI/180,n=(r.lng-t.lng)*Math.PI/180,o=Math.sin(e/2),i=Math.sin(n/2),s=o*o+Math.cos(t.lat*Math.PI/180)*Math.cos(r.lat*Math.PI/180)*i*i;return 6371*(2*Math.atan2(Math.sqrt(s),Math.sqrt(1-s)))},Wn=(t,r)=>{const e=r.fromLatLngToDivPixel(t.getNorthEast()),n=r.fromLatLngToDivPixel(t.getSouthWest());return Dn(e),Dn(n),{northEast:e,southWest:n}},$n=(t,r)=>{let{northEast:e,southWest:n}=t;return e.x+=r,e.y-=r,n.x-=r,n.y+=r,{northEast:e,southWest:n}},Vn=(t,r)=>{let{northEast:e,southWest:n}=t;const o=r.fromDivPixelToLatLng(n),i=r.fromDivPixelToLatLng(e);return new google.maps.LatLngBounds(o,i)};class Gn{constructor(t){let{maxZoom:r=16}=t;this.maxZoom=r}noop(t){let{markers:r}=t;return Kn(r)}}class Hn extends Gn{constructor(t){var{viewportPadding:r=60}=t;super(Tn(t,["viewportPadding"])),this.viewportPadding=60,this.viewportPadding=r}calculate(t){let{markers:r,map:e,mapCanvasProjection:n}=t;const o=e.getZoom();return Dn(o),o>=this.maxZoom?{clusters:this.noop({markers:r}),changed:!1}:{clusters:this.cluster({markers:Fn(e,n,r,this.viewportPadding),map:e,mapCanvasProjection:n})}}}const Kn=t=>t.map(t=>new zn({position:Zn.getPosition(t),markers:[t]}));var Yn,Xn,Jn,Qn,to,ro,eo,no,oo,io,so,ao,uo,co,fo,lo,ho,po,mo,go,vo={};function yo(){if(Qn)return Jn;Qn=1;var t=function(){if(Xn)return Yn;Xn=1;var t=ct(),r=ut();return Yn=function(e){if("Function"===t(e))return r(e)}}(),r=kt(),e=v(),n=t(t.bind);return Jn=function(t,o){return r(t),void 0===o?t:e?n(t,o):function(){return t.apply(o,arguments)}},Jn}function wo(){return ro?to:(ro=1,to={})}function bo(){if(no)return eo;no=1;var t=nr(),r=wo(),e=t("iterator"),n=Array.prototype;return eo=function(t){return void 0!==t&&(r.Array===t||n[e]===t)}}function Eo(){if(ao)return so;ao=1;var t=function(){if(io)return oo;io=1;var t={};return t[nr()("toStringTag")]="z",oo="[object z]"===String(t)}(),r=pt(),e=ct(),n=nr()("toStringTag"),o=Object,i="Arguments"===e(function(){return arguments}());return so=t?e:function(t){var s,a,u;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(a=function(t,r){try{return t[r]}catch(t){}}(s=o(t),n))?a:i?e(s):"Object"===(u=e(s))&&r(s.callee)?"Arguments":u}}function ko(){if(co)return uo;co=1;var t=Eo(),r=xt(),e=ft(),n=wo(),o=nr()("iterator");return uo=function(i){if(!e(i))return r(i,o)||r(i,"@@iterator")||n[t(i)]}}function xo(){if(lo)return fo;lo=1;var t=y(),r=kt(),e=yr(),n=Et(),o=ko(),i=TypeError;return fo=function(s,a){var u=arguments.length<2?o(s):a;if(r(u))return e(t(u,s));throw new i(n(s)+" is not iterable")},fo}function Mo(){if(po)return ho;po=1;var t=yo(),r=y(),e=yr(),n=Et(),o=bo(),i=fe(),s=gt(),a=xo(),u=ko(),c=Cn(),f=TypeError,l=function(t,r){this.stopped=t,this.result=r},h=l.prototype;return ho=function(p,m,d){var g,v,y,w,b,E,k,x=d&&d.that,M=!(!d||!d.AS_ENTRIES),O=!(!d||!d.IS_RECORD),P=!(!d||!d.IS_ITERATOR),C=!(!d||!d.INTERRUPTED),S=t(m,x),j=function(t){return g&&c(g,"normal"),new l(!0,t)},A=function(t){return M?(e(t),C?S(t[0],t[1],j):S(t[0],t[1])):C?S(t,j):S(t)};if(O)g=p.iterator;else if(P)g=p;else{if(!(v=u(p)))throw new f(n(p)+" is not iterable");if(o(v)){for(y=0,w=i(p);w>y;y++)if((b=A(p[y]))&&s(h,b))return b;return new l(!1)}g=a(p,v)}for(E=O?p.next:g.next;!(k=r(E,g)).done;){try{b=A(k.value)}catch(t){c(g,"throw",t)}if("object"==typeof b&&b&&s(h,b))return b}return new l(!1)}}go||(go=1,function(){if(mo)return vo;mo=1;var t=qe(),r=y(),e=Mo(),n=kt(),o=yr(),i=Mn(),s=Cn(),a=_n()("forEach",TypeError);t({target:"Iterator",proto:!0,real:!0,forced:a},{forEach:function(t){o(this);try{n(t)}catch(t){s(this,"throw",t)}if(a)return r(a,this,t);var u=i(this),c=0;e(u,function(r){t(r,c++)},{IS_RECORD:!0})}})}());var Oo=Object.getOwnPropertyNames,Po=Object.getOwnPropertySymbols,Co=Object.prototype.hasOwnProperty;function So(t,r){return function(e,n,o){return t(e,n,o)&&r(e,n,o)}}function jo(t){return function(r,e,n){if(!r||!e||"object"!=typeof r||"object"!=typeof e)return t(r,e,n);var o=n.cache,i=o.get(r),s=o.get(e);if(i&&s)return i===e&&s===r;o.set(r,e),o.set(e,r);var a=t(r,e,n);return o.delete(r),o.delete(e),a}}function Ao(t){return Oo(t).concat(Po(t))}var Io=Object.hasOwn||function(t,r){return Co.call(t,r)};function _o(t,r){return t===r||!t&&!r&&t!=t&&r!=r}var To=Object.getOwnPropertyDescriptor,Lo=Object.keys;function qo(t,r,e){var n=t.length;if(r.length!==n)return!1;for(;n-- >0;)if(!e.equals(t[n],r[n],n,n,t,r,e))return!1;return!0}function Ro(t,r){return _o(t.getTime(),r.getTime())}function Zo(t,r){return t.name===r.name&&t.message===r.message&&t.cause===r.cause&&t.stack===r.stack}function zo(t,r){return t===r}function Do(t,r,e){var n=t.size;if(n!==r.size)return!1;if(!n)return!0;for(var o,i,s=new Array(n),a=t.entries(),u=0;(o=a.next())&&!o.done;){for(var c=r.entries(),f=!1,l=0;(i=c.next())&&!i.done;)if(s[l])l++;else{var h=o.value,p=i.value;if(e.equals(h[0],p[0],u,l,t,r,e)&&e.equals(h[1],p[1],h[0],p[0],t,r,e)){f=s[l]=!0;break}l++}if(!f)return!1;u++}return!0}var Fo=_o;function No(t,r,e){var n=Lo(t),o=n.length;if(Lo(r).length!==o)return!1;for(;o-- >0;)if(!Ho(t,r,e,n[o]))return!1;return!0}function Uo(t,r,e){var n,o,i,s=Ao(t),a=s.length;if(Ao(r).length!==a)return!1;for(;a-- >0;){if(!Ho(t,r,e,n=s[a]))return!1;if(o=To(t,n),i=To(r,n),(o||i)&&(!o||!i||o.configurable!==i.configurable||o.enumerable!==i.enumerable||o.writable!==i.writable))return!1}return!0}function Bo(t,r){return _o(t.valueOf(),r.valueOf())}function Wo(t,r){return t.source===r.source&&t.flags===r.flags}function $o(t,r,e){var n=t.size;if(n!==r.size)return!1;if(!n)return!0;for(var o,i,s=new Array(n),a=t.values();(o=a.next())&&!o.done;){for(var u=r.values(),c=!1,f=0;(i=u.next())&&!i.done;){if(!s[f]&&e.equals(o.value,i.value,o.value,i.value,t,r,e)){c=s[f]=!0;break}f++}if(!c)return!1}return!0}function Vo(t,r){var e=t.length;if(r.length!==e)return!1;for(;e-- >0;)if(t[e]!==r[e])return!1;return!0}function Go(t,r){return t.hostname===r.hostname&&t.pathname===r.pathname&&t.protocol===r.protocol&&t.port===r.port&&t.hash===r.hash&&t.username===r.username&&t.password===r.password}function Ho(t,r,e,n){return!("_owner"!==n&&"__o"!==n&&"__v"!==n||!t.$$typeof&&!r.$$typeof)||Io(r,n)&&e.equals(t[n],r[n],n,n,t,r,e)}var Ko=Array.isArray,Yo="function"==typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView:null,Xo=Object.assign,Jo=Object.prototype.toString.call.bind(Object.prototype.toString);var Qo=ti();function ti(t){void 0===t&&(t={});var r,e=t.circular,n=void 0!==e&&e,o=t.createInternalComparator,i=t.createState,s=t.strict,a=void 0!==s&&s,u=function(t){var r=t.circular,e=t.createCustomConfig,n=t.strict,o={areArraysEqual:n?Uo:qo,areDatesEqual:Ro,areErrorsEqual:Zo,areFunctionsEqual:zo,areMapsEqual:n?So(Do,Uo):Do,areNumbersEqual:Fo,areObjectsEqual:n?Uo:No,arePrimitiveWrappersEqual:Bo,areRegExpsEqual:Wo,areSetsEqual:n?So($o,Uo):$o,areTypedArraysEqual:n?Uo:Vo,areUrlsEqual:Go};if(e&&(o=Xo({},o,e(o))),r){var i=jo(o.areArraysEqual),s=jo(o.areMapsEqual),a=jo(o.areObjectsEqual),u=jo(o.areSetsEqual);o=Xo({},o,{areArraysEqual:i,areMapsEqual:s,areObjectsEqual:a,areSetsEqual:u})}return o}(t),c=function(t){var r=t.areArraysEqual,e=t.areDatesEqual,n=t.areErrorsEqual,o=t.areFunctionsEqual,i=t.areMapsEqual,s=t.areNumbersEqual,a=t.areObjectsEqual,u=t.arePrimitiveWrappersEqual,c=t.areRegExpsEqual,f=t.areSetsEqual,l=t.areTypedArraysEqual,h=t.areUrlsEqual;return function(t,p,m){if(t===p)return!0;if(null==t||null==p)return!1;var d=typeof t;if(d!==typeof p)return!1;if("object"!==d)return"number"===d?s(t,p,m):"function"===d&&o(t,p,m);var g=t.constructor;if(g!==p.constructor)return!1;if(g===Object)return a(t,p,m);if(Ko(t))return r(t,p,m);if(null!=Yo&&Yo(t))return l(t,p,m);if(g===Date)return e(t,p,m);if(g===RegExp)return c(t,p,m);if(g===Map)return i(t,p,m);if(g===Set)return f(t,p,m);var v=Jo(t);return"[object Date]"===v?e(t,p,m):"[object RegExp]"===v?c(t,p,m):"[object Map]"===v?i(t,p,m):"[object Set]"===v?f(t,p,m):"[object Object]"===v?"function"!=typeof t.then&&"function"!=typeof p.then&&a(t,p,m):"[object URL]"===v?h(t,p,m):"[object Error]"===v?n(t,p,m):"[object Arguments]"===v?a(t,p,m):("[object Boolean]"===v||"[object Number]"===v||"[object String]"===v)&&u(t,p,m)}}(u);return function(t){var r=t.circular,e=t.comparator,n=t.createState,o=t.equals,i=t.strict;if(n)return function(t,s){var a=n(),u=a.cache,c=void 0===u?r?new WeakMap:void 0:u,f=a.meta;return e(t,s,{cache:c,equals:o,meta:f,strict:i})};if(r)return function(t,r){return e(t,r,{cache:new WeakMap,equals:o,meta:void 0,strict:i})};var s={cache:void 0,equals:o,meta:void 0,strict:i};return function(t,r){return e(t,r,s)}}({circular:n,comparator:c,createState:i,equals:o?o(c):(r=c,function(t,e,n,o,i,s,a){return r(t,e,a)}),strict:a})}ti({strict:!0}),ti({circular:!0}),ti({circular:!0,strict:!0}),ti({createInternalComparator:function(){return _o}}),ti({strict:!0,createInternalComparator:function(){return _o}}),ti({circular:!0,createInternalComparator:function(){return _o}}),ti({circular:!0,createInternalComparator:function(){return _o},strict:!0});const ri=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];class ei{static from(t){if(!(t instanceof ArrayBuffer))throw new Error("Data must be an instance of ArrayBuffer.");const[r,e]=new Uint8Array(t,0,2);if(219!==r)throw new Error("Data does not appear to be in a KDBush format.");const n=e>>4;if(1!==n)throw new Error(`Got v${n} data when expected v1.`);const o=ri[15&e];if(!o)throw new Error("Unrecognized array type.");const[i]=new Uint16Array(t,2,1),[s]=new Uint32Array(t,4,1);return new ei(s,i,o,t)}constructor(t,r=64,e=Float64Array,n){if(isNaN(t)||t<0)throw new Error(`Unpexpected numItems value: ${t}.`);this.numItems=+t,this.nodeSize=Math.min(Math.max(+r,2),65535),this.ArrayType=e,this.IndexArrayType=t<65536?Uint16Array:Uint32Array;const o=ri.indexOf(this.ArrayType),i=2*t*this.ArrayType.BYTES_PER_ELEMENT,s=t*this.IndexArrayType.BYTES_PER_ELEMENT,a=(8-s%8)%8;if(o<0)throw new Error(`Unexpected typed array class: ${e}.`);n&&n instanceof ArrayBuffer?(this.data=n,this.ids=new this.IndexArrayType(this.data,8,t),this.coords=new this.ArrayType(this.data,8+s+a,2*t),this._pos=2*t,this._finished=!0):(this.data=new ArrayBuffer(8+i+s+a),this.ids=new this.IndexArrayType(this.data,8,t),this.coords=new this.ArrayType(this.data,8+s+a,2*t),this._pos=0,this._finished=!1,new Uint8Array(this.data,0,2).set([219,16+o]),new Uint16Array(this.data,2,1)[0]=r,new Uint32Array(this.data,4,1)[0]=t)}add(t,r){const e=this._pos>>1;return this.ids[e]=e,this.coords[this._pos++]=t,this.coords[this._pos++]=r,e}finish(){const t=this._pos>>1;if(t!==this.numItems)throw new Error(`Added ${t} items when expected ${this.numItems}.`);return ni(this.ids,this.coords,this.nodeSize,0,this.numItems-1,0),this._finished=!0,this}range(t,r,e,n){if(!this._finished)throw new Error("Data not yet indexed - call index.finish().");const{ids:o,coords:i,nodeSize:s}=this,a=[0,o.length-1,0],u=[];for(;a.length;){const c=a.pop()||0,f=a.pop()||0,l=a.pop()||0;if(f-l<=s){for(let s=l;s<=f;s++){const a=i[2*s],c=i[2*s+1];a>=t&&a<=e&&c>=r&&c<=n&&u.push(o[s])}continue}const h=l+f>>1,p=i[2*h],m=i[2*h+1];p>=t&&p<=e&&m>=r&&m<=n&&u.push(o[h]),(0===c?t<=p:r<=m)&&(a.push(l),a.push(h-1),a.push(1-c)),(0===c?e>=p:n>=m)&&(a.push(h+1),a.push(f),a.push(1-c))}return u}within(t,r,e){if(!this._finished)throw new Error("Data not yet indexed - call index.finish().");const{ids:n,coords:o,nodeSize:i}=this,s=[0,n.length-1,0],a=[],u=e*e;for(;s.length;){const c=s.pop()||0,f=s.pop()||0,l=s.pop()||0;if(f-l<=i){for(let e=l;e<=f;e++)ai(o[2*e],o[2*e+1],t,r)<=u&&a.push(n[e]);continue}const h=l+f>>1,p=o[2*h],m=o[2*h+1];ai(p,m,t,r)<=u&&a.push(n[h]),(0===c?t-e<=p:r-e<=m)&&(s.push(l),s.push(h-1),s.push(1-c)),(0===c?t+e>=p:r+e>=m)&&(s.push(h+1),s.push(f),s.push(1-c))}return a}}function ni(t,r,e,n,o,i){if(o-n<=e)return;const s=n+o>>1;oi(t,r,s,n,o,i),ni(t,r,e,n,s-1,1-i),ni(t,r,e,s+1,o,1-i)}function oi(t,r,e,n,o,i){for(;o>n;){if(o-n>600){const s=o-n+1,a=e-n+1,u=Math.log(s),c=.5*Math.exp(2*u/3),f=.5*Math.sqrt(u*c*(s-c)/s)*(a-s/2<0?-1:1);oi(t,r,e,Math.max(n,Math.floor(e-a*c/s+f)),Math.min(o,Math.floor(e+(s-a)*c/s+f)),i)}const s=r[2*e+i];let a=n,u=o;for(ii(t,r,n,e),r[2*o+i]>s&&ii(t,r,n,o);a<u;){for(ii(t,r,a,u),a++,u--;r[2*a+i]<s;)a++;for(;r[2*u+i]>s;)u--}r[2*n+i]===s?ii(t,r,n,u):(u++,ii(t,r,u,o)),u<=e&&(n=u+1),e<=u&&(o=u-1)}}function ii(t,r,e,n){si(t,e,n),si(r,2*e,2*n),si(r,2*e+1,2*n+1)}function si(t,r,e){const n=t[r];t[r]=t[e],t[e]=n}function ai(t,r,e,n){const o=t-e,i=r-n;return o*o+i*i}const ui={minZoom:0,maxZoom:16,minPoints:2,radius:40,extent:512,nodeSize:64,log:!1,generateId:!1,reduce:null,map:t=>t},ci=Math.fround||(fi=new Float32Array(1),t=>(fi[0]=+t,fi[0]));var fi;class li{constructor(t){this.options=Object.assign(Object.create(ui),t),this.trees=new Array(this.options.maxZoom+1),this.stride=this.options.reduce?7:6,this.clusterProps=[]}load(t){const{log:r,minZoom:e,maxZoom:n}=this.options;r&&console.time("total time");const o=`prepare ${t.length} points`;r&&console.time(o),this.points=t;const i=[];for(let r=0;r<t.length;r++){const e=t[r];if(!e.geometry)continue;const[n,o]=e.geometry.coordinates,s=ci(mi(n)),a=ci(di(o));i.push(s,a,1/0,r,-1,1),this.options.reduce&&i.push(0)}let s=this.trees[n+1]=this._createTree(i);r&&console.timeEnd(o);for(let t=n;t>=e;t--){const e=+Date.now();s=this.trees[t]=this._createTree(this._cluster(s,t)),r&&console.log("z%d: %d clusters in %dms",t,s.numItems,+Date.now()-e)}return r&&console.timeEnd("total time"),this}getClusters(t,r){let e=((t[0]+180)%360+360)%360-180;const n=Math.max(-90,Math.min(90,t[1]));let o=180===t[2]?180:((t[2]+180)%360+360)%360-180;const i=Math.max(-90,Math.min(90,t[3]));if(t[2]-t[0]>=360)e=-180,o=180;else if(e>o){const t=this.getClusters([e,n,180,i],r),s=this.getClusters([-180,n,o,i],r);return t.concat(s)}const s=this.trees[this._limitZoom(r)],a=s.range(mi(e),di(i),mi(o),di(n)),u=s.data,c=[];for(const t of a){const r=this.stride*t;c.push(u[r+5]>1?hi(u,r,this.clusterProps):this.points[u[r+3]])}return c}getChildren(t){const r=this._getOriginId(t),e=this._getOriginZoom(t),n="No cluster with the specified id.",o=this.trees[e];if(!o)throw new Error(n);const i=o.data;if(r*this.stride>=i.length)throw new Error(n);const s=this.options.radius/(this.options.extent*Math.pow(2,e-1)),a=i[r*this.stride],u=i[r*this.stride+1],c=o.within(a,u,s),f=[];for(const r of c){const e=r*this.stride;i[e+4]===t&&f.push(i[e+5]>1?hi(i,e,this.clusterProps):this.points[i[e+3]])}if(0===f.length)throw new Error(n);return f}getLeaves(t,r,e){r=r||10,e=e||0;const n=[];return this._appendLeaves(n,t,r,e,0),n}getTile(t,r,e){const n=this.trees[this._limitZoom(t)],o=Math.pow(2,t),{extent:i,radius:s}=this.options,a=s/i,u=(e-a)/o,c=(e+1+a)/o,f={features:[]};return this._addTileFeatures(n.range((r-a)/o,u,(r+1+a)/o,c),n.data,r,e,o,f),0===r&&this._addTileFeatures(n.range(1-a/o,u,1,c),n.data,o,e,o,f),r===o-1&&this._addTileFeatures(n.range(0,u,a/o,c),n.data,-1,e,o,f),f.features.length?f:null}getClusterExpansionZoom(t){let r=this._getOriginZoom(t)-1;for(;r<=this.options.maxZoom;){const e=this.getChildren(t);if(r++,1!==e.length)break;t=e[0].properties.cluster_id}return r}_appendLeaves(t,r,e,n,o){const i=this.getChildren(r);for(const r of i){const i=r.properties;if(i&&i.cluster?o+i.point_count<=n?o+=i.point_count:o=this._appendLeaves(t,i.cluster_id,e,n,o):o<n?o++:t.push(r),t.length===e)break}return o}_createTree(t){const r=new ei(t.length/this.stride|0,this.options.nodeSize,Float32Array);for(let e=0;e<t.length;e+=this.stride)r.add(t[e],t[e+1]);return r.finish(),r.data=t,r}_addTileFeatures(t,r,e,n,o,i){for(const s of t){const t=s*this.stride,a=r[t+5]>1;let u,c,f;if(a)u=pi(r,t,this.clusterProps),c=r[t],f=r[t+1];else{const e=this.points[r[t+3]];u=e.properties;const[n,o]=e.geometry.coordinates;c=mi(n),f=di(o)}const l={type:1,geometry:[[Math.round(this.options.extent*(c*o-e)),Math.round(this.options.extent*(f*o-n))]],tags:u};let h;h=a||this.options.generateId?r[t+3]:this.points[r[t+3]].id,void 0!==h&&(l.id=h),i.features.push(l)}}_limitZoom(t){return Math.max(this.options.minZoom,Math.min(Math.floor(+t),this.options.maxZoom+1))}_cluster(t,r){const{radius:e,extent:n,reduce:o,minPoints:i}=this.options,s=e/(n*Math.pow(2,r)),a=t.data,u=[],c=this.stride;for(let e=0;e<a.length;e+=c){if(a[e+2]<=r)continue;a[e+2]=r;const n=a[e],f=a[e+1],l=t.within(a[e],a[e+1],s),h=a[e+5];let p=h;for(const t of l){const e=t*c;a[e+2]>r&&(p+=a[e+5])}if(p>h&&p>=i){let t,i=n*h,s=f*h,m=-1;const d=(e/c<<5)+(r+1)+this.points.length;for(const n of l){const u=n*c;if(a[u+2]<=r)continue;a[u+2]=r;const f=a[u+5];i+=a[u]*f,s+=a[u+1]*f,a[u+4]=d,o&&(t||(t=this._map(a,e,!0),m=this.clusterProps.length,this.clusterProps.push(t)),o(t,this._map(a,u)))}a[e+4]=d,u.push(i/p,s/p,1/0,d,-1,p),o&&u.push(m)}else{for(let t=0;t<c;t++)u.push(a[e+t]);if(p>1)for(const t of l){const e=t*c;if(!(a[e+2]<=r)){a[e+2]=r;for(let t=0;t<c;t++)u.push(a[e+t])}}}}return u}_getOriginId(t){return t-this.points.length>>5}_getOriginZoom(t){return(t-this.points.length)%32}_map(t,r,e){if(t[r+5]>1){const n=this.clusterProps[t[r+6]];return e?Object.assign({},n):n}const n=this.points[t[r+3]].properties,o=this.options.map(n);return e&&o===n?Object.assign({},o):o}}function hi(t,r,e){return{type:"Feature",id:t[r+3],properties:pi(t,r,e),geometry:{type:"Point",coordinates:[(n=t[r],360*(n-.5)),gi(t[r+1])]}};var n}function pi(t,r,e){const n=t[r+5],o=n>=1e4?`${Math.round(n/1e3)}k`:n>=1e3?Math.round(n/100)/10+"k":n,i=t[r+6],s=-1===i?{}:Object.assign({},e[i]);return Object.assign(s,{cluster:!0,cluster_id:t[r+3],point_count:n,point_count_abbreviated:o})}function mi(t){return t/360+.5}function di(t){const r=Math.sin(t*Math.PI/180),e=.5-.25*Math.log((1+r)/(1-r))/Math.PI;return e<0?0:e>1?1:e}function gi(t){const r=(180-360*t)*Math.PI/180;return 360*Math.atan(Math.exp(r))/Math.PI-90}class vi extends Gn{constructor(t){var{maxZoom:r,radius:e=60}=t,n=Tn(t,["maxZoom","radius"]);super({maxZoom:r}),this.markers=[],this.clusters=[],this.state={zoom:-1},this.superCluster=new li(Object.assign({maxZoom:this.maxZoom,radius:e},n))}calculate(t){let r=!1,e=t.map.getZoom();Dn(e),e=Math.round(e);const n={zoom:e};if(!Qo(t.markers,this.markers)){r=!0,this.markers=[...t.markers];const e=this.markers.map(t=>{const r=Zn.getPosition(t);return{type:"Feature",geometry:{type:"Point",coordinates:[r.lng(),r.lat()]},properties:{marker:t}}});this.superCluster.load(e)}return r||(this.state.zoom<=this.maxZoom||n.zoom<=this.maxZoom)&&(r=!Qo(this.state,n)),this.state=n,0===t.markers.length?(this.clusters=[],{clusters:this.clusters,changed:r}):(r&&(this.clusters=this.cluster(t)),{clusters:this.clusters,changed:r})}cluster(t){let{map:r}=t;const e=r.getZoom();return Dn(e),this.superCluster.getClusters([-180,-90,180,90],Math.round(e)).map(t=>this.transformCluster(t))}transformCluster(t){let{geometry:{coordinates:[r,e]},properties:n}=t;if(n.cluster)return new zn({markers:this.superCluster.getLeaves(n.cluster_id,1/0).map(t=>t.properties.marker),position:{lat:e,lng:r}});const o=n.marker;return new zn({markers:[o],position:Zn.getPosition(o)})}}var yi,wi,bi,Ei,ki,xi={};function Mi(){if(bi)return xi;bi=1;var t=qe(),r=Mo(),e=kt(),n=yr(),o=Mn(),i=Cn(),s=_n(),a=function(){if(wi)return yi;wi=1;var t=v(),r=Function.prototype,e=r.apply,n=r.call;return yi="object"==typeof Reflect&&Reflect.apply||(t?n.bind(e):function(){return n.apply(e,arguments)}),yi}(),u=d(),c=TypeError,f=u(function(){[].keys().reduce(function(){},void 0)}),l=!f&&s("reduce",c);return t({target:"Iterator",proto:!0,real:!0,forced:f||l},{reduce:function(t){n(this);try{e(t)}catch(t){i(this,"throw",t)}var s=arguments.length<2,u=s?void 0:arguments[1];if(l)return a(l,this,s?[t]:[t,u]);var f=o(this),h=0;if(r(f,function(r){s?(s=!1,u=r):u=t(u,r,h),h++},{IS_RECORD:!0}),s)throw new c("Reduce of empty iterator with no initial value");return u}}),xi}Ei||(Ei=1,Mi());class Oi{constructor(t,r){this.markers={sum:t.length};const e=r.map(t=>t.count),n=e.reduce((t,r)=>t+r,0);this.clusters={count:r.length,markers:{mean:n/r.length,sum:n,min:Math.min(...e),max:Math.max(...e)}}}}class Pi{render(t,r,e){let{count:n,position:o}=t;const i=`<svg fill="${n>Math.max(10,r.clusters.markers.mean)?"#ff0000":"#0000ff"}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 240" width="50" height="50">\n<circle cx="120" cy="120" opacity=".6" r="70" />\n<circle cx="120" cy="120" opacity=".3" r="90" />\n<circle cx="120" cy="120" opacity=".2" r="110" />\n<text x="50%" y="50%" style="fill:#fff" text-anchor="middle" font-size="50" dominant-baseline="middle" font-family="roboto,arial,sans-serif">${n}</text>\n</svg>`,s=`Cluster of ${n} markers`,a=Number(google.maps.Marker.MAX_ZINDEX)+n;if(Zn.isAdvancedMarkerAvailable(e)){const t=(new DOMParser).parseFromString(i,"image/svg+xml").documentElement;t.setAttribute("transform","translate(0 25)");const r={map:e,position:o,zIndex:a,title:s,content:t};return new google.maps.marker.AdvancedMarkerElement(r)}const u={position:o,zIndex:a,title:s,icon:{url:`data:image/svg+xml;base64,${btoa(i)}`,anchor:new google.maps.Point(25,25)}};return new google.maps.Marker(u)}}class Ci{constructor(){!function(t,r){for(let e in r.prototype)t.prototype[e]=r.prototype[e]}(Ci,google.maps.OverlayView)}}t.MarkerClustererEvents=void 0,(ki=t.MarkerClustererEvents||(t.MarkerClustererEvents={})).CLUSTERING_BEGIN="clusteringbegin",ki.CLUSTERING_END="clusteringend",ki.CLUSTER_CLICK="click",ki.GMP_CLICK="gmp-click";const Si=(t,r,e)=>{r.bounds&&e.fitBounds(r.bounds)};return t.AbstractAlgorithm=Gn,t.AbstractViewportAlgorithm=Hn,t.Cluster=zn,t.ClusterStats=Oi,t.DefaultRenderer=Pi,t.GridAlgorithm=class extends Hn{constructor(t){var{maxDistance:r=4e4,gridSize:e=40}=t;super(Tn(t,["maxDistance","gridSize"])),this.clusters=[],this.state={zoom:-1},this.maxDistance=r,this.gridSize=e}calculate(t){let{markers:r,map:e,mapCanvasProjection:n}=t;const o=e.getZoom();Dn(o);const i={zoom:o};let s=!1;return this.state.zoom>=this.maxZoom&&i.zoom>=this.maxZoom||(s=!Qo(this.state,i)),this.state=i,o>=this.maxZoom?{clusters:this.noop({markers:r}),changed:s}:{clusters:this.cluster({markers:Fn(e,n,r,this.viewportPadding),map:e,mapCanvasProjection:n})}}cluster(t){let{markers:r,map:e,mapCanvasProjection:n}=t;return this.clusters=[],r.forEach(t=>{this.addToClosestCluster(t,e,n)}),this.clusters}addToClosestCluster(t,r,e){let n=this.maxDistance,o=null;for(let r=0;r<this.clusters.length;r++){const e=this.clusters[r];Dn(e.bounds);const i=Bn(e.bounds.getCenter().toJSON(),Zn.getPosition(t).toJSON());i<n&&(n=i,o=e)}if(o)if(Dn(o.bounds),Nn(o.bounds,e,this.gridSize).contains(Zn.getPosition(t)))o.push(t);else{const r=new zn({markers:[t]});this.clusters.push(r)}else{const r=new zn({markers:[t]});this.clusters.push(r)}}},t.MarkerClusterer=class extends Ci{constructor(t){let{map:r,markers:e=[],algorithmOptions:n={},algorithm:o=new vi(n),renderer:i=new Pi,onClusterClick:s=Si}=t;super(),this.map=null,this.idleListener=null,this.markers=[...e],this.clusters=[],this.algorithm=o,this.renderer=i,this.onClusterClick=s,r&&this.setMap(r)}addMarker(t,r){this.markers.includes(t)||(this.markers.push(t),r||this.render())}addMarkers(t,r){t.forEach(t=>{this.addMarker(t,!0)}),r||this.render()}removeMarker(t,r){const e=this.markers.indexOf(t);return-1!==e&&(Zn.setMap(t,null),this.markers.splice(e,1),r||this.render(),!0)}removeMarkers(t,r){let e=!1;return t.forEach(t=>{e=this.removeMarker(t,!0)||e}),e&&!r&&this.render(),e}clearMarkers(t){this.markers.length=0,t||this.render()}render(){const r=this.getMap();if(r instanceof google.maps.Map&&r.getProjection()){google.maps.event.trigger(this,t.MarkerClustererEvents.CLUSTERING_BEGIN,this);const{clusters:e,changed:n}=this.algorithm.calculate({markers:this.markers,map:r,mapCanvasProjection:this.getProjection()});if(n||null==n){const t=new Set;for(const r of e)1==r.markers.length&&t.add(r.markers[0]);const r=[];for(const e of this.clusters)null!=e.marker&&(1==e.markers.length?t.has(e.marker)||Zn.setMap(e.marker,null):r.push(e.marker));this.clusters=e,this.renderClusters(),requestAnimationFrame(()=>r.forEach(t=>Zn.setMap(t,null)))}google.maps.event.trigger(this,t.MarkerClustererEvents.CLUSTERING_END,this)}}onAdd(){const t=this.getMap();Dn(t),this.idleListener=t.addListener("idle",this.render.bind(this)),this.render()}onRemove(){this.idleListener&&google.maps.event.removeListener(this.idleListener),this.reset()}reset(){this.markers.forEach(t=>Zn.setMap(t,null)),this.clusters.forEach(t=>t.delete()),this.clusters=[]}renderClusters(){const r=new Oi(this.markers,this.clusters),e=this.getMap();this.clusters.forEach(n=>{if(1===n.markers.length)n.marker=n.markers[0];else if(n.marker=this.renderer.render(n,r,e),n.markers.forEach(t=>Zn.setMap(t,null)),this.onClusterClick){const r=Zn.isAdvancedMarker(n.marker)?t.MarkerClustererEvents.GMP_CLICK:t.MarkerClustererEvents.CLUSTER_CLICK;n.marker.addListener(r,r=>{google.maps.event.trigger(this,t.MarkerClustererEvents.CLUSTER_CLICK,n),this.onClusterClick(r,n,e)})}Zn.setMap(n.marker,e)})}},t.MarkerUtils=Zn,t.NoopAlgorithm=class extends Gn{constructor(t){super(Tn(t,[]))}calculate(t){let{markers:r,map:e,mapCanvasProjection:n}=t;return{clusters:this.cluster({markers:r,map:e,mapCanvasProjection:n}),changed:!1}}cluster(t){return this.noop(t)}},t.SuperClusterAlgorithm=vi,t.SuperClusterViewportAlgorithm=class extends Hn{constructor(t){var{maxZoom:r,radius:e=60,viewportPadding:n=60}=t,o=Tn(t,["maxZoom","radius","viewportPadding"]);super({maxZoom:r,viewportPadding:n}),this.markers=[],this.clusters=[],this.superCluster=new li(Object.assign({maxZoom:this.maxZoom,radius:e},o)),this.state={zoom:-1,view:[0,0,0,0]}}calculate(t){const r=this.getViewportState(t);let e=!Qo(this.state,r);if(!Qo(t.markers,this.markers)){e=!0,this.markers=[...t.markers];const r=this.markers.map(t=>{const r=Zn.getPosition(t);return{type:"Feature",geometry:{type:"Point",coordinates:[r.lng(),r.lat()]},properties:{marker:t}}});this.superCluster.load(r)}return e&&(this.clusters=this.cluster(t),this.state=r),{clusters:this.clusters,changed:e}}cluster(t){const r=this.getViewportState(t);return this.superCluster.getClusters(r.view,r.zoom).map(t=>this.transformCluster(t))}transformCluster(t){let{geometry:{coordinates:[r,e]},properties:n}=t;if(n.cluster)return new zn({markers:this.superCluster.getLeaves(n.cluster_id,1/0).map(t=>t.properties.marker),position:{lat:e,lng:r}});const o=n.marker;return new zn({markers:[o],position:Zn.getPosition(o)})}getViewportState(t){const r=t.map.getZoom(),e=t.map.getBounds();return Dn(r),Dn(e),{zoom:Math.round(r),view:Un(e,t.mapCanvasProjection,this.viewportPadding)}}},t.defaultOnClusterClickHandler=Si,t.distanceBetweenPoints=Bn,t.extendBoundsToPaddedViewport=Nn,t.extendPixelBounds=$n,t.filterMarkersToPaddedViewport=Fn,t.getPaddedViewport=Un,t.noop=Kn,t.pixelBoundsToLatLngBounds=Vn,t}({}); 28288//# sourceMappingURL=index.min.js.map
28289 28290 28291; 28292////pf: javascript/stats/components/heatmap/index.js 28293 28294/********************************************************************** 28295 * @fileoverview Heatmap component index 28296 * 28297 **********************************************************************/ 28298 28299/** 28300 * The following are for importing and caching the google maps libraries 28301 */ 28302 28303let MAP_LIBRARY = null; 28304let MARKER_LIBRARY = null; 28305 28306// eslint-disable-next-line no-redeclare, no-unused-vars 28307async function getMapLibrary() { 28308 if (!MAP_LIBRARY) { 28309 MAP_LIBRARY = await google.maps.importLibrary('maps'); 28310 } 28311 return MAP_LIBRARY; 28312} 28313 28314// eslint-disable-next-line no-redeclare, no-unused-vars 28315const getMarkerLibrary = async () => { 28316 if (!MARKER_LIBRARY) { 28317 MARKER_LIBRARY = await google.maps.importLibrary('marker'); 28318 } 28319 return MARKER_LIBRARY; 28320}; 28321 28322/******************************************************************************************** 28323 * Adds the Google Maps API script to the page. This is the recommended way to load the API. 28324 * 28325 ********************************************************************************************/ 28326// prettier-ignore 28327// eslint-disable-next-line no-redeclare, no-unused-vars 28328function loadGoogleMapApiScript(googleApiKey) { 28329 // eslint-disable-next-line no-async-promise-executor, semi, no-console 28330 return (g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({ 28331 key: googleApiKey, 28332 v: "beta", 28333 libraries: "visualization", 28334 }); 28335} 28336 28337 28338; 28339////pf: javascript/stats/components/heatmap/types.js 28340 28341/** 28342 * @fileoverview HeatMap Types 28343 */ 28344 28345// eslint-disable-next-line no-redeclare 28346const HeatMapTypes = { 28347 table: { 28348 REGISTRANTS: 'registrants', 28349 GROUPED: 'grouped' 28350 }, 28351 grouping: { 28352 NONE: 'none', 28353 PARTICIPANT_STATE: 'ParticipantState', 28354 PARTICIPANT_COUNTY: 'ParticipantCounty', 28355 PARTICIPANT_CITY: 'ParticipantCity', 28356 PARTICIPANT_ZIPCODE: 'ParticipantZip', 28357 PROGRAM_STATE: 'ProgramState', 28358 PROGRAM_COUNTY: 'ProgramCounty', 28359 PROGRAM_CITY: 'ProgramCity', 28360 PROGRAM_ZIPCODE: 'ProgramZipCode' 28361 } 28362}; 28363 28364 28365; 28366////pf: javascript/stats/components/heatmap/color.utils.js 28367 28368function hexToRgb(hex) { 28369 const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; 28370 const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec( 28371 hex.replace(shorthandRegex, (m, r, g, b) => r + r + g + g + b + b) 28372 ); 28373 const rgb = { 28374 r: parseInt(result[1], 16), 28375 g: parseInt(result[2], 16), 28376 b: parseInt(result[3], 16) 28377 }; 28378 return result ? rgb : null; 28379} 28380 28381function rgbToHex(r, g, b) { 28382 return '#' + [r, g, b].map(x => x.toString(16).padStart(2, '0')).join(''); 28383} 28384 28385/** 28386 * Get a color between two colors at a percent 28387 * 28388 * @param {string} color1 - hex color 28389 * @param {string} color2 - hex color 28390 * @param {decimal} percent - decimal between 0 and 1 28391 * @returns hex color 28392 */ 28393// eslint-disable-next-line no-unused-vars 28394function getPercentBetweenColors(color1, color2, percent) { 28395 const color1RGB = hexToRgb(color1); 28396 const color2RGB = hexToRgb(color2); 28397 28398 const r = Math.floor(color1RGB.r + (color2RGB.r - color1RGB.r) * percent); 28399 const g = Math.floor(color1RGB.g + (color2RGB.g - color1RGB.g) * percent); 28400 const b = Math.floor(color1RGB.b + (color2RGB.b - color1RGB.b) * percent); 28401 28402 return rgbToHex(r, g, b); 28403} 28404 28405function quantile(values, q) { 28406 values.sort((a, b) => a - b); 28407 const pos = (values.length - 1) * q; 28408 const base = Math.floor(pos); 28409 const rest = pos - base; 28410 if (values[base + 1] !== undefined) { 28411 return values[base] + rest * (values[base + 1] - values[base]); 28412 } else { 28413 return values[base]; 28414 } 28415} 28416 28417function interpolateColor(color1, color2, factor) { 28418 const result = color1.slice(); 28419 for (let i = 0; i < 3; i++) { 28420 result[i] = Math.round(result[i] + factor * (color2[i] - color1[i])); 28421 } 28422 return result; 28423} 28424 28425// eslint-disable-next-line no-unused-vars 28426function getColorForValue(value, dataValues, colorRange) { 28427 const sortedData = [...dataValues].sort((a, b) => a - b); 28428 const quantileValue = quantile(sortedData, value / 100); // Assuming value is a percentage 28429 const [startColor, endColor] = colorRange.map(color => { 28430 const match = color.match(/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/); 28431 return [parseInt(match[1], 16), parseInt(match[2], 16), parseInt(match[3], 16)]; 28432 }); 28433 const interpolatedColor = interpolateColor(startColor, endColor, quantileValue / 100); 28434 const hex = rgbToHex(...interpolatedColor); 28435 // return `rgb(${interpolatedColor.join(',')})`; 28436 return hex; 28437} 28438 28439// regex for determining if a string is a valid hex color 28440// eslint-disable-next-line no-unused-vars 28441function checkHexColor(str) { 28442 return /^#[0-9A-F]{6}$/i.test(str); 28443} 28444 28445// eslint-disable-next-line no-unused-vars, no-redeclare 28446function getColorForPercentage(percentage, colors) { 28447 const boundPercent = Math.max(0, Math.min(1, percentage)); // not really a percent, but a ratio 28448 const segment = 1 / (colors.length - 1); 28449 const index = Math.min(Math.floor(boundPercent / segment), colors.length - 2); 28450 28451 if (isNaN(index)) 28452 return colors[0]; 28453 28454 const factor = (boundPercent - segment * index) / segment; 28455 28456 const regex = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/; 28457 const startColor = colors[index] 28458 .match(regex) 28459 .slice(1) 28460 .map(n => parseInt(n, 16)); 28461 28462 const endColor = colors[index + 1] 28463 .match(regex) 28464 .slice(1) 28465 .map(n => parseInt(n, 16)); 28466 28467 const interpolatedColor = interpolateColor(startColor, endColor, factor); 28468 28469 return rgbToHex(...interpolatedColor); 28470} 28471
28472// Different color schemes 28473const mapColorScheme = {}; 28474 28475// prettier-ignore 28476mapColorScheme.light_orange_blue = [ 28477 '#f79256', 28478 '#fbd1a2', 28479 '#7dcfb6', 28480 '#00b2ca', 28481 '#1d4e89' 28482]; 28483 28484mapColorScheme.yellow_gray = [ 28485 '#2e5266', 28486 '#4e6d7f', 28487 '#6e8898', 28488 '#879daa', 28489 '#9fb1bc', 28490 '#b9c1c4', 28491 '#d3d0cb', 28492 '#dbc888', 28493 '#e2c044' 28494]; 28495 28496// prettier-ignore 28497mapColorScheme.blue = [ 28498 '#03045e', 28499 '#023e8a', 28500 '#0077b6', 28501 '#0096c7', 28502 '#00b4d8', 28503 '#48cae4', 28504 '#90e0ef' 28505]; 28506 28507// prettier-ignore 28508mapColorScheme.blue_red = [ 28509 "rgba(255, 255, 255, 0)", 28510 '#00ffff', 28511 '#00dfff', 28512 '#00bfff', 28513 '#0080ff', 28514 '#0040ff', 28515 '#003fff', 28516 '#0000ff', 28517 '#0000df', 28518 '#0000bf', 28519 '#00009f', 28520 '#00007f', 28521 '#3f005b', 28522 '#7f003f', 28523 '#bf001f', 28524 '#ff0000', 28525]; 28526 28527 28528; 28529////pf: javascript/stats/components/heatmap/marker.utils.js 28530 28531 28532/*********************************************************************************************** 28533 * @fileoverview Marker utils for heatmap component. Generates markers for the map. 28534 * @see https://developers.google.com/maps/documentation/javascript/markers 28535 **********************************************************************************************/ 28536 28537// eslint-disable-next-line no-unused-vars, no-redeclare 28538const createSimpleMarker = (map, position, title) => 28539 new google.maps.Marker({ map, position, title }); 28540 28541// eslint-disable-next-line no-unused-vars, no-redeclare 28542const createSmallMarker = async (map, position) => { 28543 const { AdvancedMarkerElement, PinElement } = await getMarkerLibrary(); 28544 const pinScaled = new PinElement({ 28545 background: '#25aae1', 28546 borderColor: '#fff', 28547 // glyph: "", 28548 glyphColor: 'white', 28549 scale: 0.5 28550 }); 28551 const marker = new AdvancedMarkerElement({ 28552 map, 28553 position, 28554 content: pinScaled.element 28555 }); 28556 return marker; 28557}; 28558 28559// eslint-disable-next-line no-unused-vars 28560const createMarkerViewBackground = async (map, position, title) => { 28561 const { AdvancedMarkerElement, PinElement } = await getMarkerLibrary(); 28562 28563 const pinBackground = new PinElement({ 28564 background: '#25aae1' 28565 }); 28566 const marker = new AdvancedMarkerElement({ 28567 map, 28568 position, 28569 content: pinBackground.element 28570 }); 28571 return marker; 28572}; 28573 28574// eslint-disable-next-line no-unused-vars 28575const createMarkerHtmlSimple = async (map, position, content) => { 28576 const { AdvancedMarkerElement } = await getMarkerLibrary(); 28577 28578 const marker = new AdvancedMarkerElement({ 28579 map, 28580 position, 28581 content 28582 }); 28583 28584 return marker; 28585}; 28586 28587// eslint-disable-next-line no-unused-vars 28588const createBoundsMarker = async (map, position) => { 28589 const { AdvancedMarkerElement, PinElement } = await getMarkerLibrary(); 28590 const pinScaled = new PinElement({ 28591 background: '#0CB0A9', 28592 borderColor: '#fff', 28593 // glyph: "", 28594 glyphColor: 'white', 28595 scale: 1.25 28596 }); 28597 const marker = new AdvancedMarkerElement({ 28598 map, 28599 position, 28600 content: pinScaled.element 28601 }); 28602 return marker; 28603}; 28604 28605 28606;
28607////pf: javascript/stats/components/heatmap/adapters/geographic-group.js 28608/*********************************************************************************** 28609 * JS Adapter for GeographicReportingGrouping. This represents a "grouping" of data 28610 * by zip code, city, state, or region. 28611 * @see GeographicLocation.cs 28612 * 28613 * TODO: Consider making a class that this and GeographicRegistrant can extend from 28614 * 28615 * @param {*} data 28616 * @param {*} grouping 28617 * @returns 28618 ***********************************************************************************/ 28619// eslint-disable-next-line no-redeclare, no-unused-vars 28620const GeographicGrouped = async function (data, grouping) { 28621 const { 28622 GroupingValue, 28623 AvgMilesToEvent, 28624 // AgeCount, 28625 GenderCount, 28626 ProfileIdCount, 28627 UserIdCount, 28628 SportCount, 28629 BrandCount, 28630 ProgramCount, 28631 IncomeEstimate, 28632 ReturnCount, 28633 TotalAgi, 28634 GooglePlaceId 28635 // Latitude, 28636 // Longitude 28637 } = data; 28638 28639 const locationName = GroupingValue; 28640 28641 // helper function to check location data 28642 const _checkLocation = () => { 28643 const stats = { 28644 GroupingValue, 28645 grouping, 28646 GooglePlaceId 28647 }; 28648 28649 stats.hasPlaceId = !!GooglePlaceId; 28650 28651 return stats; 28652 }; 28653 28654 /** 28655 * Create HTML content for marker 28656 * @returns 28657 */ 28658 function toContent() { 28659 const keys = { 28660 ProfileIdCount: "Profiles", 28661 UserIdCount: "Accounts", 28662 AvgMilesToEvent: "Avg Miles to Event", 28663 GenderCount: "Gender", 28664 SportCount: "Sports", 28665 BrandCount: "Brands", 28666 ProgramCount: "Programs", 28667 IncomeEstimate: "Avg Household Income" 28668 } 28669 28670 const listItems = Object.keys(keys) 28671 .filter(key => data[key] !== '' && data[key] !== null && data[key] !== undefined) 28672 .map(key => `<li><strong>${keys[key]}</strong> ${data[key]}</li>`) 28673 .join(''); 28674 28675 return `<h3 class="info-window__header">${locationName}</h3> 28676 <ul class="info-window__content registrants-data">${listItems}</ul>`; 28677 } 28678 28679 return { 28680 ...data, 28681 locationName, 28682 toContent, 28683 _checkLocation 28684 }; 28685}; 28686 28687 28688;
28689////pf: javascript/stats/components/heatmap/adapters/geographic-registrant.js 28690/******************************************************************************** 28691 * The JS Adapter for GeographicReportingParticipant. This represents a single 28692 * registrant/participant. 28693 * @see GeographicLocation.cs 28694 * 28695 * @param {*} data 28696 * @returns 28697 ********************************************************************************/ 28698// eslint-disable-next-line no-redeclare, no-unused-vars 28699const GeographicRegistrant = function (data) { 28700 const { 28701 // UserId, 28702 ProfileId, 28703 Gender, 28704 Age, 28705 Zip, 28706 City, 28707 CityGooglePlaceId, 28708 State, 28709 Latitude, 28710 Longitude, 28711 SportName, 28712 BrandName, 28713 Type, 28714 MilesToProgram, 28715 // ProgramLatitude, 28716 // ProgramLongitude, 28717 ProgramZip, 28718 ProgramCity, 28719 ProgramCityGooglePlaceId, 28720 ProgramState, 28721 ProgramRegion, 28722 // ProgramId, 28723 ProgramName, 28724 // ReturnCount, 28725 TotalAgi 28726 } = data; 28727 28728 const _checkLocation = () => { 28729 let locationInfo = { 28730 Zip, 28731 City, 28732 CityGooglePlaceId, 28733 State, 28734 Latitude, 28735 Longitude, 28736 ProgramZip, 28737 ProgramCity, 28738 ProgramCityGooglePlaceId, 28739 ProgramState, 28740 ProgramRegion 28741 }; 28742 28743 locationInfo.hasLatLng = Latitude && Longitude; 28744 locationInfo.hasProgramLatLng = locationInfo.ProgramLatitude && locationInfo.ProgramLongitude; 28745 locationInfo.hasPlaceId = !!CityGooglePlaceId; 28746 locationInfo.hasProgramPlaceId = !!ProgramCityGooglePlaceId; 28747 28748 return locationInfo; 28749 }; 28750 28751 const locationName = `${City}, ${State} ${Zip}`; 28752 28753 const toContent = () => { 28754 const keys = { 28755 Gender: "Gender", 28756 Age: "Age", 28757 SportName: "Sport", 28758 BrandName: "Brand", 28759 ProgramName: "Program", 28760 Type: "Type", 28761 MilesToProgram: "Avg Miles to Program", 28762 IncomeEstimate: "Avg Household Income" 28763 }; 28764 28765 const format = (k, i) => { 28766 if (k === 'Gender') { 28767 return i ? 'Boys' : 'Girls'; 28768 } 28769 28770 return i; 28771 }; 28772 28773 const listItems = Object.keys(keys) 28774 .filter(key => data[key] !== '' && data[key] !== null && data[key] !== undefined) 28775 .map(key => `<li><strong>${keys[key]}</strong> ${format(key, data[key])}</li>`) 28776 .join(''); 28777 28778 return `<ul>${listItems}</ul>`; 28779 }; 28780 28781 return { 28782 ...data, 28783 locationName, 28784 toContent, 28785 _checkLocation 28786 }; 28787}; 28788 28789/******************************************************************************** 28790 * Consolidated Registrant/Participant data, when multiple registrants are at the 28791 * same location. 28792 * 28793 * @param {*} data 28794 * @returns 28795 ********************************************************************************/ 28796// eslint-disable-next-line no-redeclare, no-unused-vars 28797const ConsolidatedRegistrants = function (data) { 28798 const { Latitude, Longitude, Registrants } = data; 28799 const count = Registrants.length; 28800 28801 const _checkLocation = () => { 28802 const stats = { 28803 Latitude, 28804 Longitude 28805 }; 28806 28807 stats.hasLatLng = Latitude && Longitude; 28808 28809 return stats; 28810 }; 28811 28812 const zipcodes = Registrants.map(r => r.Zip); 28813 const uniqueZipcodes = [...new Set(zipcodes)]; 28814 const firstRegistrant = Registrants[0]; 28815 28816 const locale = firstRegistrant && uniqueZipcodes.length === 1 28817 ? `${firstRegistrant.City}, ${firstRegistrant.State} ${firstRegistrant.Zip}` 28818 : uniqueZipcodes.join(', '); 28819 28820 const toContent = () => { 28821 return `<h3 class="info-window__header"><i class="fa-regular fa-mailbox"></i> ${locale}</h3> 28822 <ul class="info-window__content registrants-data"> 28823 ${Registrants.map(r => r.toContent()).join('')} 28824 </ul>`; 28825 }; 28826 28827 return { 28828 ...data, 28829 toContent, 28830 _checkLocation, 28831 count 28832 }; 28833}; 28834 28835; 28836////pf: javascript/stats/components/heatmap/heatmap.js 28837 28838/*********************************************************************************** 28839 * Heatmap.js - This could be named better. It's the main file for the heatmap. 28840 * It contains the main functions for loading and rendering the map. 28841 * 28842 * @param {*} elementId 28843 * @returns { load } - load function 28844 ***********************************************************************************/ 28845// eslint-disable-next-line no-unused-vars 28846const HeatMap = function (elementId, googleApiKey, mapId) { 28847 let GOOGLE_API_IS_LOADED = false; 28848 28849 // Data 28850 const geodata = { 28851 registrants: [], 28852 registrantsConsolidated: [], 28853 grouped: [],
28854 _groupingBy: null, 28855 _isProgramLevel: false, 28856 places: {}, 28857 }; 28858 28859 // Map/Map API props 28860 let mapInstance = null; 28861 let bounds = null; 28862 let infoWindow = null; 28863 let featureLayer = null; 28864 let markers = []; 28865 let activeMarkers = []; 28866 28867 const US_CENTER = { lat: 39.8283, lng: -98.5795 }; 28868 let startingZoom = 4; 28869 let startingCenter = US_CENTER; // Default to center of US 28870 28871 const init = async () => { 28872 if (GOOGLE_API_IS_LOADED) return; 28873 try { 28874 await loadGoogleMapApiScript(googleApiKey); 28875 GOOGLE_API_IS_LOADED = true; 28876 } catch (error) { 28877 // eslint-disable-next-line no-console 28878 console.error('heatmap.init =>', error); 28879 throw new Error('failed to load google maps script'); 28880 } 28881 }; 28882 28883 /****************************************************** 28884 * Create empty map, initalize bounds and infoWindow 28885 * 28886 * @returns map instance 28887 ******************************************************/ 28888 const ensureMapInitialized = async () => { 28889 if (mapInstance) return; 28890 await initializeMap(); 28891 }; 28892 28893 const initializeMap = async () => { 28894 try { 28895 const { Map } = await getMapLibrary(); 28896 bounds = new google.maps.LatLngBounds(); 28897 infoWindow = new google.maps.InfoWindow(); 28898 28899 const mapDivId = createMapDiv(); 28900 28901 mapInstance = new Map(document.getElementById(mapDivId), { 28902 center: startingCenter, 28903 zoom: startingZoom, 28904 mapId: mapId, 28905 disableDefaultUI: true, 28906 mapTypeControl: false, 28907 zoomControl: true, 28908 zoomControlOptions: { 28909 position: google.maps.ControlPosition.RIGHT_TOP 28910 } 28911 }); 28912 28913 // if map is clicked other than infowindow thats open, close infowindow 28914 mapInstance.addListener('click', () => { 28915 infoWindow.close(); 28916 }); 28917 } catch (error) { 28918 // eslint-disable-next-line no-console 28919 console.error('ensureMapInitialized :: error', error); 28920 throw new Error('failed to create empty map'); 28921 } 28922 }; 28923 28924 /****************************************************** 28925 * Load data and initialize map, the "main" function 28926 * 28927 * @param {*} registrantData 28928 * @param {*} groupedData 28929 * @param {*} grouping 28930 * @returns 28931 ******************************************************/ 28932 const load = async ({ registrantData, groupedData, grouping }) => { 28933 // _props = { registrantData, groupedData, grouping }; 28934 if (!registrantData && !groupedData) { 28935 // eslint-disable-next-line no-console 28936 return console.warn('No data to load'); 28937 } 28938 28939 try { 28940 if (registrantData) { 28941 // TODO: Location data missing for "Event" groupings 28942 if (grouping && grouping.includes('Event')) { 28943 registrantData = registrantData.map(r => { 28944 r.Latitude = r.ProgramLatitude; 28945 r.Longitude = r.ProgramLongitude; 28946 r.CityGooglePlaceId = r.ProgramCityGooglePlaceId; 28947 r.City = r.ProgramCity; 28948 r.State = r.ProgramState; 28949 r.Zip = r.ProgramZip; 28950 return r; 28951 }); 28952 } 28953 geodata.registrants = await loadRegistrantData(registrantData); 28954 } 28955 if (groupedData) { 28956 if (!grouping) throw new Error('Missing grouping'); 28957 geodata.grouped = await loadGroupedData(groupedData, grouping); 28958 geodata._groupingBy = grouping; 28959 } 28960 28961 await render(geodata); 28962 } catch (error) { 28963 // eslint-disable-next-line no-console 28964 console.error('heatmap.load =>', error); 28965 return; 28966 } 28967 }; 28968 28969 // Utility function to filter data with lat/lng 28970 const filterWithLatLng = data => data.filter(d => d.Latitude && d.Longitude); 28971 28972 /********************************************************************************* 28973 * This is the main render function. It renders the map, and adds markers and 28974 * boundaries based on the data passed in. This should be used to re-render the 28975 * map when the data changes, especially client-side. 28976 * 28977 * @param {*} geodata 28978 *********************************************************************************/ 28979 async function render(geodata) { 28980 await ensureMapInitialized(); 28981 28982 let boundableData = []; 28983 28984 try { 28985 if (geodata.grouped && geodata.grouped.length > 0) { 28986 if (!geodata._groupingBy) 28987 throw new Error('Missing groupingBy'); 28988 28989 if ( 28990 geodata._groupingBy === HeatMapTypes.grouping.PARTICIPANT_CITY || 28991 geodata._groupingBy === HeatMapTypes.grouping.PARTICIPANT_COUNTY || 28992 geodata._groupingBy === HeatMapTypes.grouping.PARTICIPANT_STATE || 28993 geodata._groupingBy === HeatMapTypes.grouping.PROGRAM_CITY || 28994 geodata._groupingBy === HeatMapTypes.grouping.PROGRAM_COUNTY || 28995 geodata._groupingBy === HeatMapTypes.grouping.PROGRAM_STATE 28996 ) { 28997 loadFeatureLayer(geodata.grouped, geodata._groupingBy); 28998 initBoundaries(geodata.grouped); 28999 29000 await markConsolidatedLocations(geodata.grouped); 29001 } 29002 else if (geodata._groupingBy === HeatMapTypes.grouping.PARTICIPANT_ZIPCODE 29003 || geodata._groupingBy === HeatMapTypes.grouping.PROGRAM_ZIPCODE) { 29004 createHeatMapLayer(geodata.grouped); 29005 } 29006 29007 boundableData.push(...geodata.grouped); 29008 } 29009 29010 if (geodata._groupingBy === HeatMapTypes.grouping.PARTICIPANT_ZIPCODE || !geodata._groupingBy) 29011 { 29012 if (geodata.registrants && geodata.registrants.length > 0) { 29013 const locationsWithLatLng = filterWithLatLng(geodata.registrants); 29014 const consolidatedLocations = consolidateRegistrantData(locationsWithLatLng); 29015 await markConsolidatedLocations(consolidatedLocations); 29016 boundableData.push(...consolidatedLocations); 29017 } 29018 } 29019 29020 await markBrandLocations(geodata.registrants); 29021 29022 setBoundsByData(boundableData); 29023 } catch (error) { 29024 // eslint-disable-next-line no-console 29025 console.error('heatmap.render =>', error); 29026 return; 29027 } 29028 } 29029 29030 /****************************************************** 29031 * Load registrant data 29032 * 29033 * @param {*} data 29034 * @returns 29035 ******************************************************/ 29036 const loadRegistrantData = async data => { 29037 try { 29038 const registrants = data.map(GeographicRegistrant); 29039 return registrants; 29040 } catch (error) { 29041 // eslint-disable-next-line no-console 29042 console.error('loadRegistrantData error =>', error); 29043 } 29044 }; 29045 29046 /****************************************************** 29047 * Load grouped data 29048 * 29049 * @param {*} data 29050 * @param {*} grouping 29051 * @returns 29052 ******************************************************/ 29053 const loadGroupedData = async (data, grouping) => { 29054 return await Promise.all(data.map(d => GeographicGrouped(d, grouping))); 29055 }; 29056 29057 /******************************************************************************** 29058 * Load feature layer 29059 * 29060 * @see https://developers.google.com/maps/documentation/javascript/layers 29061 * 29062 * @param {*} data 29063 * @param {*} grouping 29064 * @returns 29065 ********************************************************************************/ 29066 const loadFeatureLayer = (data, grouping) => { 29067 let _featureType = null; 29068 29069 if (grouping === HeatMapTypes.grouping.PARTICIPANT_ZIPCODE 29070 || grouping === HeatMapTypes.grouping.PROGRAM_ZIPCODE) { 29071 _featureType = google.maps.FeatureType.POSTAL_CODE; 29072 } 29073 if (grouping === HeatMapTypes.grouping.PARTICIPANT_STATE 29074 || grouping === HeatMapTypes.grouping.PROGRAM_STATE) { 29075 _featureType = google.maps.FeatureType.ADMINISTRATIVE_AREA_LEVEL_1; 29076 } 29077 if (grouping === HeatMapTypes.grouping.PARTICIPANT_COUNTY 29078 || grouping === HeatMapTypes.grouping.PROGRAM_COUNTY) { 29079 _featureType = google.maps.FeatureType.ADMINISTRATIVE_AREA_LEVEL_2; 29080 } 29081 if (grouping === HeatMapTypes.grouping.PARTICIPANT_CITY 29082 || grouping === HeatMapTypes.grouping.PROGRAM_CITY) { 29083 _featureType = google.maps.FeatureType.LOCALITY; 29084 } 29085 29086 if (!_featureType) return false; 29087 29088 featureLayer = mapInstance.getFeatureLayer(_featureType); 29089 return true; 29090 }; 29091 29092 /********************************************************************************** 29093 * Style feature layer. This is fills boundaries with a color based on the number 29094 * of registrants in that area. The color is determined by a color scale. This is 29095 * used for state and city level boundaries. 29096 * 29097 * @param {*} places - Places with GooglePlaceId 29098 * @param {*} props - maxProfileIdCount, or other props 29099 * @returns 29100 **********************************************************************************/ 29101 const featureLayerStyle = (places, props) => { 29102 const { maxProfileIdCount } = props; 29103 29104 return (featureLayer.style = options => { 29105 const placeFeature = options.feature; 29106 const featureProfileIdCount = places[placeFeature.placeId]?.ProfileIdCount; 29107 29108 if (!featureProfileIdCount) { 29109 return; // otherwise maps will style the whole country 29110 } 29111 29112 let percentOfMax = 0; 29113 29114 if (maxProfileIdCount > 0 && featureProfileIdCount !== undefined) { 29115 percentOfMax = featureProfileIdCount / maxProfileIdCount; 29116 } 29117 29118 let strokeColor = colorScale(Math.sqrt(percentOfMax)); 29119 29120 const style = { 29121 strokeColor: strokeColor, 29122 strokeOpacity: 1.0, 29123 strokeWeight: 2.0, 29124 fillColor: strokeColor, 29125 fillOpacity: 1.0 29126 }; 29127 29128 return { 29129 ...style, 29130 fillOpacity: 0.6 29131 }; 29132 }); 29133 }; 29134 29135 /******************************************************************************** 29136 * Parse a weight value for a heat map layer. If the value is null or undefined, 29137 * return 0. Otherwise, return the value. 29138 * 29139 * @param {*} data - Registrant data 29140 * @returns {Array} - Array of objects with location and weight 29141 ********************************************************************************/ 29142 const parseHeatLayerData = data => { 29143 return data 29144 .map(d => { 29145 if (!d.Latitude || !d.Longitude) return; 29146 const location = new google.maps.LatLng(d.Latitude, d.Longitude); 29147 const weight = d.ProfileIdCount || 0; 29148 return { location, weight }; 29149 }) 29150 .filter(d => d); 29151 }; 29152 29153 /**ðºï¸ð¥********************************************************************* 29154 * Create heat map layer. 29155 * https://developers.google.com/maps/documentation/javascript/heatmaplayer 29156 * 29157 * @param {*} data 29158 * @returns 29159 ***************************************************************************/ 29160 function createHeatMapLayer(data) { 29161 const heatLayerData = parseHeatLayerData(data); 29162 29163 const heatLayer = new google.maps.visualization.HeatmapLayer({ 29164 data: heatLayerData 29165 });
29166 heatLayer.setMap(mapInstance); 29167 29168 heatLayer.set('radius', 25); 29169 heatLayer.set('opacity', 0.75); 29170 } 29171 29172 /************************************************************************************ 29173 * Set map bounds by data, when map is idle, set starting props and add reset button 29174 * 29175 * @param {*} data 29176 ************************************************************************************/ 29177 function setBoundsByData(data) { 29178 data.forEach(d => { 29179 const { Latitude, Longitude } = d; 29180 if (!Latitude || !Longitude) return; 29181 const latLng = { lat: Latitude, lng: Longitude }; 29182 bounds.extend(latLng); 29183 }); 29184 29185 const listener = google.maps.event.addListener(mapInstance, 'idle', () => { 29186 setStartingProps(); 29187 29188 // This is the only spot this works, otherwise it's called multiple times 29189 //TODO: button removed until it is updated to work better 29190 //const resetButton = createResetButton(); 29191 //mapInstance.controls[google.maps.ControlPosition.TOP_LEFT].push(resetButton); 29192 google.maps.event.removeListener(listener); 29193 }); 29194 } 29195 29196 /** 29197 * Set starting props for map, center and zoom 29198 */ 29199 function setStartingProps() { 29200 // TODO: need to bound to the state instead of the marker of a state 29201 if (bounds.equals(new google.maps.LatLngBounds())) { 29202 mapInstance.setZoom(startingZoom); 29203 mapInstance.panTo(startingCenter); 29204 } 29205 else 29206 mapInstance.fitBounds(bounds); 29207 29208 startingCenter = mapInstance.getCenter(); 29209 startingZoom = mapInstance.getZoom(); 29210 if (startingZoom > 7) startingZoom = 7; 29211 mapInstance.setZoom(startingZoom); 29212 } 29213 29214 /********************************************************************************* 29215 * Consolidated locations are places with multiple registrants. This function 29216 * marks the location with a marker, and adds a count of registrants. Single-user 29217 * icon is used for a single registrant, and a group icon is used for multiple. 29218 * 29219 * @param {*} locations 29220 *********************************************************************************/ 29221 async function markConsolidatedLocations(locations) { 29222 const { AdvancedMarkerElement } = await getMarkerLibrary(); 29223 29224 async function markConsolidatedLocation(location) { 29225 const { Latitude, Longitude, ProfileIdCount, count } = location; 29226 const useCount = ProfileIdCount || count; 29227 29228 try { 29229 const position = new google.maps.LatLng(Latitude, Longitude); 29230 const content = document.createElement('div'); 29231 content.className = 'custom-marker'; 29232 content.innerHTML = 29233 useCount > 1 29234 ? `<i class='fa-solid fa-users'></i> ${useCount.toLocaleString()}` 29235 : `<i class='fa-solid fa-user'></i>`; 29236 29237 const marker = new AdvancedMarkerElement({ 29238 position, 29239 content 29240 }); 29241 29242 marker.count = useCount; 29243 29244 addMarkerInfoWindow(marker, location.toContent()); 29245 29246 return marker; 29247 } catch (error) { 29248 // eslint-disable-next-line no-console 29249 console.error('markConsolidatedLocations :: error', error); 29250 return null; 29251 } 29252 } 29253 29254 // add markers for each 29255 for (let location of locations) { 29256 const marker = await markConsolidatedLocation(location); 29257 if (marker) markers.push(marker); 29258 } 29259 29260 await clusterMarkers(markers); 29261 } 29262 29263 async function markBrandLocations(locations) { 29264 const { AdvancedMarkerElement } = await getMarkerLibrary(); 29265 const brandLocations = locations.filter(i => i.IsBrandOffice); 29266 brandLocations.forEach(location => { 29267 29268 const { Latitude, Longitude, BrandName } = location; 29269 29270 try { 29271 const position = new google.maps.LatLng(Latitude, Longitude); 29272 const content = document.createElement('div'); 29273 content.className = 'custom-marker brand'; 29274 content.innerHTML = `<i class='fa-solid fa-star'></i> ${BrandName}`; 29275 29276 const marker = new AdvancedMarkerElement({ 29277 position, 29278 content 29279 }); 29280 29281 marker.setMap(mapInstance); 29282 } catch (error) { 29283 // eslint-disable-next-line no-console 29284 console.error('markConsolidatedLocations :: error', error); 29285 return null; 29286 } 29287 29288 }); 29289 } 29290 29291 /****************************************************************************************** 29292 * Data is grouped by lat/lng belonging to a zip code, shared by multiple registrants. 29293 * This function consolidates the data into a single location, with a count of registrants. 29294 * 29295 * @param {*} locations 29296 * @returns 29297 ******************************************************************************************/ 29298 const consolidateRegistrantData = locations => { 29299 const locationsByLatLng = {}; 29300 29301 locations.forEach(location => { 29302 const { Latitude, Longitude } = location;
29303 const latLng = `${Latitude},${Longitude}`; 29304 if (!locationsByLatLng[latLng]) locationsByLatLng[latLng] = []; 29305 locationsByLatLng[latLng].push(location); 29306 }); 29307 29308 const consolidatedLocations = Object.values(locationsByLatLng).map(locations => { 29309 const { Latitude, Longitude } = locations[0]; 29310 const props = { 29311 Latitude, 29312 Longitude, 29313 Registrants: locations 29314 }; 29315 return ConsolidatedRegistrants(props); 29316 }); 29317 29318 return consolidatedLocations; 29319 }; 29320 29321 /******************************************************************************** 29322 * Combine markers into clusters. Requires google's marker-clusterer library. 29323 * https://developers.google.com/maps/documentation/javascript/marker-clustering 29324 * 29325 * @param {*} markers 29326 ********************************************************************************/ 29327 async function clusterMarkers(markers) { 29328 new markerClusterer.MarkerClusterer({ 29329 markers, 29330 map: mapInstance, 29331 onClusterClick: (e, cluster, map) => { 29332 const boundsWithPadding = new google.maps.LatLngBounds(); 29333 const padding = 0.06; 29334 const ne = cluster.bounds.getNorthEast();
29335 const sw = cluster.bounds.getSouthWest(); 29336 const neNew = new google.maps.LatLng(ne.lat() + padding, ne.lng() + padding); 29337 const swNew = new google.maps.LatLng(sw.lat() - padding, sw.lng() - padding); 29338 boundsWithPadding.extend(neNew); 29339 boundsWithPadding.extend(swNew); 29340 map.fitBounds(boundsWithPadding); 29341 infoWindow.close(); 29342 }, 29343 renderer: new ClusterMarkerRenderer() 29344 }); 29345 } 29346 29347 // very similar to example from https://googlemaps.github.io/js-markerclusterer/public/renderers/ 29348 class ClusterMarkerRenderer { 29349 render(item, stats) { 29350 const { count, position } = item; 29351 const sum = item.markers.reduce((a, i) => a + i.count, 0); 29352 // ideally this would be sum of count in this cluster over the max sum of a cluster, but that isn't available 29353 const color = colorScale(Math.sqrt((sum / count) / stats.clusters.markers.max)); 29354 29355 const svg = window.btoa(` 29356 <svg fill="${color}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 240"> 29357 <circle cx="120" cy="120" opacity=".8" r="70" /> 29358 </svg>`); 29359 29360 return new google.maps.Marker({ 29361 position, 29362 icon: { 29363 url: `data:image/svg+xml;base64,${svg}`, 29364 scaledSize: new google.maps.Size(75, 75), 29365 }, 29366 label: { 29367 text: sum.toLocaleString(), 29368 color: "rgba(255,255,255,0.9)", 29369 fontSize: "12px", 29370 }, 29371 zIndex: Number(google.maps.Marker.MAX_ZINDEX) + count, 29372 }); 29373 } 29374 } 29375 29376 // * Marker visibility functions. These are not currently used, but may be useful. 29377 29378 // // function setMapOnAllMarkers(mapInstance) { 29379 // // markers.forEach(marker => marker.setMap(mapInstance)); 29380 // // } 29381 29382 // // function hideAllMarkers() { 29383 // // setMapOnAllMarkers(null); 29384 // // } 29385 29386 // // function showAllMarkers() { 29387 // // setMapOnAllMarkers(mapInstance); 29388 // // } 29389 29390 // // function hideMarker(marker) { 29391 // // marker.setMap(null); 29392 // // } 29393 29394 /************************************************************ 29395 * Initialize boundaries for feature layer 29396 * 29397 * @param {Array} _data - Processed data with GooglePlaceId 29398 ***********************************************************/ 29399 async function initBoundaries(_data) { 29400 const dataWithPlaceId = _data.filter(d => d.GooglePlaceId); 29401 29402 dataWithPlaceId.forEach(d => { 29403 geodata.places[d.GooglePlaceId] = {...d}; 29404 }); 29405 29406 const maxProfileIdCount = Math.max(...dataWithPlaceId.map(d => d.ProfileIdCount)); 29407 29408 featureLayerStyle(geodata.places, { maxProfileIdCount }); 29409 29410 featureLayer.addListener('click', handleBoundsClick); 29411 } 29412 29413 /************************************************ 29414 * Color scale for boundaries 29415 * 29416 * @param {*} value 29417 * @returns 29418 ***********************************************/ 29419 const colorScale = value => { 29420 const colors = [ 29421 '#00CC00', 29422 '#66CC00', 29423 '#CCCC00', 29424 '#CC6600', 29425 '#CC0000', 29426 ]; 29427 return getColorForPercentage(value, colors); 29428 }; 29429 29430 function handleBoundsClick(e) { 29431 activeMarkers.forEach(marker => marker.setMap(null)); 29432 activeMarkers = []; 29433 setBoundedLocation(e); 29434 } 29435 29436 /**************************************************************************************** 29437 * Gets the location of the clicked boundary, and sets the map bounds to that location. 29438 * 29439 * @param {*} event 29440 * @returns 29441 ****************************************************************************************/ 29442 async function setBoundedLocation(e) { 29443 const { placeId } = e.features[0]; 29444 29445 addBoundsMarker(placeId, e.latLng); 29446 } 29447 29448 /**************************************************************************** 29449 * Adds a custom HTML marker to the map for the given area that was clicked. 29450 * @param {*} placeId 29451 * @param {*} position 29452 * @returns 29453 ***************************************************************************/ 29454 async function addBoundsMarker(placeId, position) { 29455 const { AdvancedMarkerElement } = await getMarkerLibrary(); 29456 29457 const location = geodata.places[placeId]; 29458 if (location.marker) { 29459 location.marker.setMap(mapInstance); 29460 return; 29461 } 29462 29463 const marker = new AdvancedMarkerElement({ 29464 map: mapInstance, 29465 position, 29466 content: buildBoundsMarkerContent(location), 29467 title: location.Name 29468 }); 29469 29470 marker.addListener('click', () => { 29471 marker.setMap(null); 29472 }); 29473 29474 location.marker = marker; 29475 activeMarkers.push(location.marker); 29476 } 29477 29478 /****************************************************** 29479 * Build HTML content for bounds marker 29480 * 29481 * @param {*} location 29482 * @returns 29483 *****************************************************/ 29484 function buildBoundsMarkerContent(location) { 29485 const content = document.createElement('div'); 29486 content.classList.add('bounds-marker__content'); 29487 content.innerHTML = location.toContent(); 29488 return content; 29489 } 29490 29491 /**************************************************************** 29492 * Create map div, similar to the KPI tile on the dashboard. 29493 * 29494 * @returns 29495 ***************************************************************/ 29496 const createMapDiv = () => { 29497 const $container = $(`#${elementId}`); 29498 if ($container.hasClass('kpi-tile')) return 'map-instance'; 29499 29500 $container.addClass('kpi-tile'); 29501 $container.append(` 29502 <header> 29503 <div class="header-group"> 29504 <a href="#" data-tooltip></a> 29505 <h2 class="title">Map</h2> 29506 <div data-controls></div> 29507 </div> 29508 </header> 29509 `); 29510 29511 const $body = $('<div class="kpi-tile-body"><div id="map-instance"></div></div>'); 29512 $container.append($body); 29513 29514 return 'map-instance'; 29515 }; 29516 29517 /******************************************** 29518 * Add InfoWindow to a marker 29519 * 29520 * @param {*} marker 29521 * @param {*} content 29522 ********************************************/ 29523 const addMarkerInfoWindow = (marker, content) => { 29524 google.maps.event.addListener(marker, 'click', () => { 29525 infoWindow.close(); 29526 infoWindow.setContent(content); 29527 29528 infoWindow.open(mapInstance, marker); 29529 mapInstance.panTo(marker.position); 29530 const zoom = mapInstance.getZoom(); 29531 if (zoom < 5) mapInstance.setZoom(5); 29532 }); 29533 }; 29534 29535 /************************************************************ 29536 * Create a reset button that re-centers map the load state. 29537 * 29538 * @returns 29539 ************************************************************/ 29540 function createResetButton() { 29541 if (document.querySelector('.map-reset-button')) return; 29542 29543 const controlButton = document.createElement('button'); 29544 29545 controlButton.className = 'map-reset-button'; 29546 controlButton.style.display = 'none'; 29547 controlButton.innerHTML = '<i class="fa-solid fa-compass"></i> Reset Map'; 29548 controlButton.title = 'Click to position map to center'; 29549 controlButton.type = 'button'; 29550 29551 const toggleVis = () => { 29552 const zoom = mapInstance.getZoom(); 29553 const center = mapInstance.getCenter(); 29554 if (zoom !== startingZoom || center !== startingCenter) { 29555 controlButton.style.display = 'block'; 29556 } else { 29557 controlButton.style.display = 'none'; 29558 } 29559 }; 29560 29561 mapInstance.addListener('zoom_changed', toggleVis); 29562 mapInstance.addListener('center_changed', toggleVis); 29563 29564 controlButton.addEventListener('click', () => { 29565 infoWindow.close();
29566 activeMarkers.forEach(marker => marker.setMap(null)); 29567 activeMarkers = []; 29568 29569 mapInstance.setZoom(startingZoom); 29570 mapInstance.panTo(startingCenter); 29571 controlButton.style.display = 'none'; 29572 }); 29573 29574 const controlDiv = document.createElement('div'); 29575 controlDiv.appendChild(controlButton); 29576 29577 return controlDiv; 29578 } 29579 29580 init(); 29581 ensureMapInitialized(); 29582 29583 return { 29584 load 29585 }; 29586}; 29587 29588 29589; 29590////pf: javascript/sortable-table.js 29591 29592window.SmpSortableTable = () => { 29593 const maxMobileWidth = 728; 29594 29595 const CONTAINS_STRING = "Contains"; 29596 const EQUALS_STRING = "Equals"; 29597 const NOT_EQUALS_STRING = "NotEquals"; 29598 const GREATER_THAN_STRING = "GreaterThan"; 29599 const LESSER_THAN_STRING = "LesserThan"; 29600 const TRUE_STRING = "true"; 29601 const FALSE_STRING = "false"; 29602 const NULL_STRING = "null"; 29603 29604 const BOOL_STRING = "Bool"; 29605 const NULLABLE_BOOL_STRING = "NullableBool"; 29606 29607 let mobileDisplay; 29608 29609 let wrapper; 29610 29611 let dataSource; 29612 let totalResultsLength; 29613 let shownResultsLength; 29614 let dataSourceOrig; 29615 let columnFilters; 29616 let columnFiltersOrig = []; 29617 let columns; 29618 let columnsOrig; 29619 let footers; 29620 let affiliationId; 29621 let tableIdentifier; 29622 let sortedColumn; 29623 let columnDescending; 29624 let sortCache = { 29625 column: null, 29626 ascending: null, 29627 sortedData: null 29628 }; 29629 let sortDebounceTimer; 29630 let _instanceSettings; 29631 let hasChildren; 29632 let allChildrenVisible; 29633 let allChildrenToggleCell; 29634 29635 let multilineEditingActive = false; 29636 let multilineToggleButton; 29637 29638 let table; 29639 let thead; 29640 let tbody; 29641 let afterElement; 29642 let afterElementModal;
29643 let controlContainer; 29644 let pagination; 29645 29646 let heading; 29647 let tableOptions; 29648 let customizeTable; 29649 let menuModal; 29650 let showFooter; 29651 let moveUpButton; 29652 let moveDownButton; 29653 let _title; 29654 let enabledWhenCheckedButtons; 29655 let checkboxStatus = {}; 29656 let currentPage = 1; 29657 let maxVisiblePages = 10; 29658 let pageSize = 100; 29659 let isDataSourceModified = false; 29660 29661 const keyName = 'k'; 29662 const valueName = 'v'; 29663 const formatName = 'f'; 29664 const modifiedName = 'm'; 29665 29666 function displayFormat(d) { 29667 const hasFormat = _instanceSettings.CompactPayload 29668 ? d[formatName] != null 29669 : d[formatName] !== undefined; 29670 return hasFormat ? d[formatName] : d[valueName]; 29671 } 29672 29673 function CreateTable(elementIDInput, columnsInput, dataSourceInput, footerInput, userPrefs, 29674 instanceSettings, title, justRefresh = false) { //Take data from SortableTable.cs and write HTML to display table 29675 wrapper = document.getElementById(elementIDInput); 29676 wrapper.exportDataToExcel = ExportDataToExcel; 29677 wrapper.sortTable = SortTable; 29678 wrapper.drawTable = DrawTable; 29679 wrapper.loadDataAsync = LoadDataAsync; 29680 wrapper.getSelectedTableRows = getSelectedTableRows; 29681 29682 mobileDisplay = (window.innerWidth <= maxMobileWidth); 29683 if (!wrapper) { 29684 console.warn('elementIDInput missing'); 29685 return; 29686 } 29687 29688 _instanceSettings = instanceSettings; 29689 _title = title; 29690 _userPrefs = userPrefs; 29691 29692 if (_instanceSettings.MaxVisiblePages) 29693 maxVisiblePages = _instanceSettings.MaxVisiblePages; 29694 29695 if (_instanceSettings.PageSize) 29696 pageSize = _instanceSettings.PageSize; 29697 29698 dataSourceOrig = dataSourceInput; 29699 dataSource = structuredClone(dataSourceOrig); 29700 wrapper.dataSource = () => dataSource; 29701 29702 sortCache = { column: null, ascending: null, sortedData: null }; 29703 columnsOrig = [...columnsInput]; 29704 columnsOrig.forEach(col => 29705 { 29706 col.IsClientVisible = col.IsClientVisible || false; 29707 col.IsVisible = col.IsClientVisible; 29708 }); 29709 29710 // Optimization: Pre-compute normalized sort values for all c
29710olumns and rows 29711 // Stores normalized values in row._sortValues[columnKey] for O(1) lookup during sorting 29712 const timeZoneCodes = ['EST', 'CST', 'MST', 'PST', 'Arizona', 'HST']; 29713 const dateFormats = [ 29714 moment.ISO_8601, 29715 "M/D/YY", 29716 ...timeZoneCodes.map(tz => `M/D/YY h:ma [${tz}]`) 29717 ]; 29718 29719 const normalizeValue = (value, columnValueType, dateFormats) => { 29720 if (value === null || value === undefined) 29721 value = ''; 29722 29723 switch (columnValueType) { 29724 case "String": 29725 return value.toString().toLowerCase().trim(); 29726 case "Bool": 29727 return value; 29728 case "NullableBool": 29729 return value != "" ? value : false; 29730 case "Number": 29731 return value != "" ? +(value) : 0; 29732 case "Date": 29733 return value != "" ? moment(value, dateFormats, true).valueOf() : moment(1900).valueOf(); 29734 case "NumberString": 29735 const firstNumRegex = /^\d+|\d+\b|\d+(?=\w)/g; 29736 const matchChange = String(value).match(firstNumRegex); 29737 return value != "" ? + (matchChange != null ? matchChange[0] : 0) : 0; 29738 default: 29739 if (moment(value, dateFormats, true).isValid()) { 29740 return value != "" ? moment(value, dateFormats, true).valueOf() : moment(1900).valueOf(); 29741 } 29742 else if (/^-?\d+$/.test(value)) { 29743 return value != "" ? +(value) : 0; 29744 } 29745 else if (typeof (value) != 'boolean') { 29746 return value.toString().toLowerCase().trim(); 29747 } 29748 return value; 29749 } 29750 }; 29751 29752 if (dataSourceOrig.length > 0 && columnsOrig.length > 0) { 29753 dataSourceOrig.forEach((row) => { 29754 if (!row._sortValues) { 29755 row._sortValues = {}; 29756 } 29757 29758 columnsOrig.forEach((col) => { 29759 if (col.ValueType) { 29760 let match = row.Data.find(j => j[keyName] === col.Key); 29761 let value = match?.[valueName]; 29762 29763 if (value === null && match?.[formatName] !== undefined) { 29764 value = match[formatName]; 29765 } 29766 29767 row._sortValues[col.Key] = normalizeValue(value, col.ValueType, dateFormats); 29768 } 29769 }); 29770 }); 29771 } 29772 29773 wrapper.setSelectedValues = (key, values) => { 29774 const checkboxes = [...table.querySelectorAll(`input[type=checkbox][key=${key}]`)]; 29775 checkboxes.forEach(c => { 29776 c.checked = values.includes(c.value); 29777 checkboxStatus[c.value] = c.checked; 29778 $(c).closest('tr').toggleClass('selected', c.checked); 29779 }); 29780 updateTitle(); 29781 } 29782 29783 wrapper.updateValue = ({ id, key, value, format }) => { 29784 29785 const keySearch = (r) => 29786 r[keyName].toLowerCase() === 'id' 29787 && (r[formatName] === id || r[valueName] == id || r[valueName]?.toString() === id?.toString()); 29788 29789 let row = dataSource 29790 .find(i => i.Data.some(keySearch)) 29791 ?.Data; 29792 29793 let parentRow = null; 29794 29795 if (row === undefined && hasChildren) { 29796 parentRow = dataSource 29797 .find(i => i.ChildItems.some(c => c.some(keySearch))); 29798 29799 if (parentRow) { 29800 row = parentRow.ChildItems.find(c => c.some(keySearch)); 29801 } 29802 } 29803 29804 if (row === undefined) { 29805 console.warn(`found no row with id ${id}`); 29806 return; 29807 } 29808 29809 const item = row.find(r => r[keyName].toLowerCase() === key.toLowerCase()); 29810 29811 if (item === undefined) { 29812 console.warn(`found no item with key ${key}`); 29813 return; 29814 } 29815 29816 item[modifiedName] = true; 29817 isDataSourceModified = true; 29818 sortCache = { column: null, ascending: null, sortedData: null }; 29819 29820 let searchBar = wrapper.querySelector('.table-search-bar'); 29821 if (searchBar) { 29822 if (_instanceSettings.SearchDuringModified){ 29823 searchBar.placeholder = 'Search Unmodified Columns Only'; 29824 } else { 29825 searchBar.disabled = true 29826 } 29827 } 29828 29829 if (value !== undefined) { 29830 item[valueName] = value; 29831 } 29832 29833 if (format !== undefined) { 29834 item[formatName] = format; 29835 } 29836 29837 const modified = dataSource 29838 .filter(r => r.Data.some(i => i[modifiedName])) 29839 .map(r => r.Data.map(i =>
29839 ({ [keyName]: i[keyName], [valueName]: i[valueName], [modifiedName]: i[modifiedName] }))); 29840 29841 const modifiedChildRows = dataSource 29842 .reduce((acc, r) => [...acc, ...r.ChildItems.filter(i => i.some(c => c[modifiedName]))], []) 29843 .map(r => r.map(i => ({ [keyName]: i[keyName], [valueName]: i[valueName], [modifiedName]: i[modifiedName] }))); 29844 29845 $(`[name=${elementIDInput}_Modified]`).val(JSON.stringify([...modified, ...modifiedChildRows])); 29846 // in case entry causes a layout shift 29847 setTimeout(() => LockColumns(), 50); 29848 }; 29849 29850 wrapper.getValue = ({ id, key }) => { 29851 const row = dataSource.find(i => i.Data.some(r => r[keyName].toLowerCase() === 'id' && (r[formatName] === id || r[valueName] == id || r[valueName]?.toString() === id ))); 29852 29853 if (row === undefined) { 29854 console.warn(`found no row with id ${id}`); 29855 return; 29856 } 29857 29858 const item = row.Data.find(r => r[keyName].toLowerCase() === key.toLowerCase()); 29859 29860 if (item === undefined) { 29861 console.warn(`found no item with key ${key}`); 29862 return; 29863 } 29864 29865 return item[valueName]; 29866 }; 29867 29868 function createUpdateScript(uiUpdate, row, columnIndex, rowId, key, value) { 29869 return function() { 29870 if (uiUpdate) { 29871 const cell = $(row).find('td').eq(columnIndex).get(0); 29872 uiUpdate(cell); 29873 } 29874 29875 wrapper.updateValue({ id: rowId, key, value }); 29876 } 29877 } 29878 29879 wrapper.updateLinkedMultilineRows = ({ id, key, value, uiUpdate, optionalCondition = null }) => { 29880 if (!multilineEditingActive) 29881 return; 29882 29883 const rows = getSelectedTableRows(); 29884 29885 const selfRow = rows 29886 .filter(r => $(r).find(`[type=checkbox][value=${id}]`).length > 0); 29887 29888 const isRowSelected = $(selfRow) 29889 .find(`[type=checkbox][value=${id}]:checked`).length > 0; 29890 29891 if (!isRowSelected) 29892 return; 29893 29894 const updatingRows = rows.filter(r => $(r).find(`[type=checkbox][value=${id}]`).length === 0); 29895 29896 const columnIndex = columns.filter(i => i.IsVisible).findIndex(col => col.Key === key); 29897 29898 if (columnIndex === undefined) 29899 console.warn(`Unable to find column ${key}`); 29900 29901 updatingRows.forEach(function (row) { 29902 const rowId = $(row).find(`[type=checkbox][value]`).attr('value'); 29903 const hasInput = $(row).find(`td[tdkey=${key}]`).find('input, select, button, textarea').length > 0; 29904 29905 if (!hasInput) 29906 return; 29907 29908 const update = createUpdateScript(uiUpdate, row, columnIndex, rowId, key, value); 29909 29910 if (optionalCondition) { 29911 optionalCondition(rowId, update); 29912 } else { 29913 update(); 29914 } 29915 29916 }); 29917 }; 29918 29919 wrapper.applyToLinkedMultilineRows = ({ uiUpdate }) => { 29920 if (!multilineEditingActive) 29921 return; 29922 29923 const rows = getSelectedTableRows(); 29924 29925 rows.forEach(function (row) { 29926 uiUpdate(row); 29927 }); 29928 }; 29929 29930 if (!columnsOrig.some(c => c.Order !== undefined)) { 29931 columnsOrig.forEach((col, index) => col.Order = index); 29932 } 29933 29934 columns = structuredClone(columnsOrig); 29935 columns.forEach(col => { 29936 columnFiltersOrig.push({ Key: col.Key, filterType: "Contains", text: "" }); 29937 }); 29938 columnFilters = structuredClone(columnFiltersOrig); 29939 29940 hasChildren = false; 29941 allChildrenVisible = false; 29942 29943 if (dataSource.some(i => i.ChildItems.length > 0)) { 29944 hasChildren = true; 29945 dataSource.forEach(i => i.IsChildrenVisible = false); 29946 } 29947 29948 footers = footerInput; 29949
29950 affiliationId = userPrefs.AffiliationId; 29951 tableIdentifier = userPrefs.TableIdentifier; 29952 columnDescending = userPrefs.ColumnDescending; //flip because the first draw on page load will flip back 29953 if (userPrefs.ColumnSettings !== null) { 29954 columns.forEach((col) => { 29955 const columnSetting = userPrefs.ColumnSettings.find(c => c.Key === col.Key); 29956 if (col.IsDraggable !== false) { //dont turn visibilty off if column is locked 29957 if (columnSetting) { 29958 col.IsVisible = columnSetting.IsVisible !== null ? columnSetting.IsVisible || false : col.IsVisible; 29959 col.Order = columnSetting.Order !== null ? columnSetting.Order : col.Order; 29960 } 29961 } 29962 }); 29963 } 29964 const card = document.createElement('div'); 29965 card.className = 'card no-flex'; 29966 29967 const spinner = document.createElement('div'); 29968 spinner.className = 'sortable-loading-spinner'; 29969 spinner.innerHTML = '<i class="fas fa-spinner fa-spin fa-3x"></i>'; 29970 card.appendChild(spinner); 29971 29972 table = document.createElement('table'); 29973 29974 CreateColumnPanel(columns, sortedColumn, null, columnFilters); 29975 29976 DrawTopNav(); 29977 29978 card.appendChild(table); 29979 wrapper.appendChild(card); 29980 29981 pagination = document.createElement('div'); 29982 pagination.className = 'pagination'; 29983 29984 if (_instanceSettings.PaginationVisible) { 29985 wrapper.appendChild(pagination); 29986 } 29987 29988 SortTable(userPrefs.SortedColumn, columnDescending); 29989 DrawTable(); 29990 29991 if (_instanceSettings.ChildrenExpandedByDefault) { 29992 ToggleAllChildren(); 29993 } 29994 29995 var globalResizeTimer = null; //delay to prevent constant table redraws when changing size 29996 window.addEventListener('resize', () => { 29997 if (globalResizeTimer != null) window.clearTimeout(globalResizeTimer); 29998 globalResizeTimer = window.setTimeout(function () { 29999 if (mobileDisplay != (window.innerWidth <= maxMobileWidth)) { 30000 mobileDisplay = (window.innerWidth <= maxMobileWidth) 30001 DrawTable(); 30002 } 30003 }, 200); 30004 }); //when table resizes redraw table to switch properly between mobile and desktop 30005 30006 document.fonts.ready.then(LockColumns); 30007 30008 if (_instanceSettings.DelayLoadUntilVisible && !justRefresh) { 30009 loadAsyncWhenVisible(wrapper); 30010 } else if (_instanceSettings.LoadImmediate && !justRefresh) { 30011 LoadDataAsync(); 30012 } 30013 } 30014 30015 function getSelectedTableRows() { 30016 const uiRowSelection = $(table).find('tr').toArray() 30017 .filter((tr) => $(tr).hasClass('selected')); 30018 30019 return uiRowSelection; 30020 } 30021 30022 function DrawTable(previousCheckboxes = false) { 30023 columns.sort((a, b) => a.Order > b.Order ? 1 : -1); //sort columns by order 30024 table.innerHTML = ''; 30025 pagination.innerHTML = ''; 30026 30027 fixOrder(columns); 30028 30029 thead = document.createElement('thead'); 30030 tbody = document.createElement('tbody'); 30031 tfoot = document.createElement('tfoot'); 30032 30033 table.appendChild(thead); 30034 table.appendChild(tbody); 30035 table.appendChild(tfoot); 30036 if (window.innerWidth <= maxMobileWidth) { 30037 DisplayMobileHeader(); 30038 DisplayMobileTable(); 30039 AlignMobileHeader(); 30040 if (showFooter !== false && _instanceSettings.FooterVisible) { 30041 DisplayMobileFooters(); 30042 } 30043 } 30044 else { 30045 DisplayTableHeadings(); 30046 DisplayTableContent(); 30047 ((showFooter !== false && _instanceSettings.FooterVisible) ? DisplayTableFooters() : null) //hides footer if some data is hidden by search 30048 30049 if (_instanceSettings.PaginationVisible) { 30050 DisplayPagination(); 30051 refillModifiedValues(); 30052 } 30053 } 30054 30055 const contentButtons = [...table.querySelectorAll('button[smp-table-func]')]; 30056 contentButtons.forEach(c => { 30057 c.type = 'button'; 30058 c.addEventListener('click', () => { 30059 const arg = { 30060 value: c.getAttribute('smp-table-value'), 30061 key: c.getAttribute('smp-table-func') 30062 }; 30063 30064 c.hasAttribute('smp-table-confirm') 30065 ? OpenModalConfirm(c.getAttribute('smp-table-confirm'), arg) 30066 : TableButtonPostBack(arg) 30067 }); 30068 }); 30069 30070 const postOnChangeInputs = [...table.querySelectorAll('input[smp-table-func]')];
30071 postOnChangeInputs.forEach(c => { 30072 c.addEventListener('change', () => { 30073 const arg = { 30074 input: c.type === 'checkbox' ? c.checked : c.value, 30075 value: c.getAttribute('smp-table-value'), 30076 key: c.getAttribute('smp-table-func') 30077 }; 30078 30079 TableButtonPostBack(arg) 30080 }); 30081 }); 30082 30083 AssignCheckboxFunctionality(); 30084 AssignRadioFunctionality(); 30085 AssignEnterKeyFunctionality(); 30086 LockColumns(); 30087 AssignMultilineFunctionality(); 30088 if (previousCheckboxes) { RecheckCheckboxes(); } 30089 30090 // TODO: this has got to be a vulnerability... what if a username or something was in a key in the script?? 30091 if (_instanceSettings.ClientScriptOnDraw) { 30092 eval(_instanceSettings.ClientScriptOnDraw); 30093 } 30094 draggableTableListenerCreator(); 30095 30096 if (_instanceSettings.SearchDuringModified) { 30097 refillModifiedValues(); 30098 } 30099 } 30100 30101 function refillModifiedValues() { 30102 // re populate modified values after table draw 30103 const modifiedValuesJson = document.querySelectorAll("[name$=_Modified]")[0].value; 30104 if (!modifiedValuesJson) return; 30105 30106 const modifiedValues = JSON.parse(modifiedValuesJson); 30107 30108 for (let row of modifiedValues) { 30109 const modifiedColKeys = new Set(row.filter(col => col[modifiedName]).map(col => col.Key)); 30110 if (!row.some(col => col[modifiedName])) continue; 30111 30112 const { [valueName]: rowId } = row.shift(); 30113 30114 row.forEach(({ [keyName]: key, [valueName]: value }) => { 30115 if (!modifiedColKeys.has(key)) return; 30116 30117 $(`[key="${key}"][keyid="${rowId}"]`).val(value); 30118 wrapper.updateValue({ id: rowId, key, value }); 30119 }); 30120 } 30121 } 30122 30123 function RecheckCheckboxes() { 30124 const checkboxes = [...table.querySelectorAll('input[type=checkbox]')]; 30125 checkboxes 30126 .filter(c => 30127 c.classList.contains('sortableCheckbox') || 30128 (c.value !== 'on' && checkboxStatus[c.value] !== undefined) 30129 ) 30130 .forEach(c => c.checked = (checkboxStatus[c.value]) ? true : false); 30131 30132 30133 UpdateCheckButtons(); 30134 } 30135 30136 function AssignMultilineFunctionality() { 30137 if (!_instanceSettings.MultilineEditingButtonIsVisible) 30138 return; 30139 30140 if (multilineToggleButton === undefined) { 30141 multilineToggleButton = document.createElement('button'); 30142 multilineToggleButton.title = 'Sync Editing of Selected Rows'; 30143 multilineToggleButton.type = 'button'; 30144 multilineToggleButton.className = 'ForwardButton menu-button custom-svg-wrapper'; 30145 multilineToggleButton.innerHTML = '<img class="custom-svg-icon" src="/images/icons/mass-change.svg"/>'; 30146 30147 controlContainer.appendChild(multilineToggleButton); 30148 30149 multilineToggleButton.addEventListener('click', () => { 30150 multilineEditingActive = !multilineEditingActive; 30151 30152 // when multiline editing active, prevent selecting more lines 30153 $(tbody) 30154 .find("[type='checkbox']") 30155 .each(function() { 30156 30157 if ($(this)?.attr('key')?.toLowerCase() != 'id') return; 30158 30159 $(this) 30160 .attr('disabled', multilineEditingActive) 30161 .closest('td.checkbox') 30162 .find('label') 30163 .css('cursor', multilineEditingActive ? 'not-allowed' : ''); 30164 }); 30165 30166 $(multilineToggleButton) 30167 .toggleClass('inverted-menu-button', multilineEditingActive); 30168 }); 30169 } 30170 30171 $(tbody) 30172 .find('input, select') 30173 .each(function () { 30174 const $input = $(this); 30175 const displayColumnIndex = $input.closest('tr').find('td').index($input.closest('td')); 30176 30177 if (displayColumnIndex === -1) 30178 return; 30179
30180 const key = columns[displayColumnIndex].Key; 30181 30182 $input.on('change', function () { 30183 const input = this; 30184 30185 if ($input.hasClass('multiline') 30186 || $input.hasClass('hasDatepicker') 30187 || input.hasAttribute('data-ignore-multiline') 30188 || $input.hasClass('as-input')) { 30189 return; 30190 } 30191 30192 const id = $input.closest('tr').find('[type=checkbox][value]').attr('value'); 30193 30194 if (input.nodeName === "SELECT") { 30195 const value = input.value; 30196 wrapper.updateLinkedMultilineRows({ 30197 id, key, value, 30198 uiUpdate: (cell) => $(cell).find('select').val(value) 30199 }); 30200 } 30201 else if (input.type == "checkbox" && input.classList.contains('multiselect')) { 30202 const value = input.checked; 30203 const data_value = $input.attr('data-value'); 30204 wrapper.updateLinkedMultilineRows({ 30205 id, key, data_value, 30206 uiUpdate: (cell) => $(cell).find('input[data-value="' + data_value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/'/g, "\\\'") + '"]').prop('checked', value) 30207 }); 30208 } 30209 else if (input.type === "checkbox") { 30210 const value = input.checked; 30211 wrapper.updateLinkedMultilineRows({ 30212 id, key, value, 30213 uiUpdate: (cell) => $(cell).find('input').prop('checked', value) 30214 }); 30215 } 30216 else if (input.type === "radio") { 30217 const value = $input.attr('value'); 30218 wrapper.updateLinkedMultilineRows({ 30219 id, key, value, 30220 uiUpdate: (cell) => $(cell).find('input[value="' + value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/'/g, "\\\'") + '"]').prop('checked', input.checked) 30221 }); 30222 } 30223 else { // should just be plain text inputs 30224 const value = input.value; 30225 wrapper.updateLinkedMultilineRows({ 30226 id, key, value, 30227 uiUpdate: (cell) => $(cell).find('input').val(value) 30228 }); 30229 } 30230 }); 30231 }); 30232 } 30233 30234 function DisplayTableHeadings() { //function to display table headings 30235 let row_1 = document.createElement('tr'); 30236 let insertArrow = document.createElement('span'); 30237 insertArrow.className = 'insert-arrow'; 30238 thead.appendChild(insertArrow); 30239 30240 row_1.addEventListener('dragover', e => { 30241 e.preventDefault(); 30242 afterElement = GetDragAfterElement(row_1, e.clientX, 'horizontal'); //get element of just-before 30243 //update html column elements live while dragging 30244 const otherDraggables = [...row_1.querySelectorAll('[draggable=true]:not(.dragging)')]; 30245 const lastItem = otherDraggables[otherDraggables.length - 1]; 30246 let arrowOffset = undefined; 30247 30248 if (afterElement) { 30249 arrowOffset = `${afterElement.offsetLeft - insertArrow.offsetWidth / 2}px`; 30250 } 30251 else if (lastItem) { 30252 arrowOffset = `${lastItem.offsetLeft + lastItem.offsetWidth - insertArrow.offsetWidth}px`; 30253 } 30254 30255 insertArrow.style.left = arrowOffset; 30256 }); 30257 var numLocked = 0; 30258 columns.forEach(col => { 30259 if (col.IsVisible === true ) { 30260 const key = col.Key; 30261 const heading = document.createElement('th'); 30262 heading.setAttribute('data-columnKey', col.Key); 30263 heading.className = col.CssClass || ''; 30264 if (col.IsDraggable) { 30265 heading.setAttribute('draggable', 'true'); 30266 heading.addEventListener('dragstart', () => { 30267 heading.classList.add('dragging'); 30268 }); 30269 heading.addEventListener('dragend', e => { 30270 heading.classList.remove('dragging'); 30271 if (isDataSourceModified) { 30272 $.fn.modalAlert.open({ content: 'Reordering edited data is not supported' }); 30273 insertArrow.style.left = '-10000px'; 30274 } 30275 else { 30276 MoveColumn(heading, afterElement, columns, 'data-columnKey'); 30277 SaveTableSettings();
30278 DrawTable(); 30279 } 30280 }); 30281 } 30282 else { 30283 heading.classList.add('is-locked'); 30284 numLocked += 1; 30285 heading.classList.add('lock' + numLocked); 30286 } 30287 if (col.IsSortable === true) { 30288 heading.className += ' sortable'; 30289 // Optimization: Debounce rapid sort requests to prevent wasted work 30290 heading.addEventListener('click', () => { 30291 clearTimeout(sortDebounceTimer); 30292 sortDebounceTimer = setTimeout(() => { 30293 SortTable(key); 30294 SaveTableSettings(); 30295 FilterTableColumns(); 30296 DrawTable(true); 30297 }, 50); 30298 }); 30299 } 30300 var label = document.createElement('span'); 30301 label.innerHTML = `<span>${col.Label + (col.InputRequired ? '<span style="color:red;"> *</span>' : '')}</span>`; 30302 heading.appendChild(label); 30303 30304 if (sortedColumn === key) { 30305 heading.className += ` highlight sortable sorted ${(columnDescending ? 'descending' : 'ascending')}`; 30306 } 30307 30308 if (columnFilters.find(f => f.Key == col.Key).text.length > 0) { 30309 var filteredIcon = document.createElement('span'); 30310 filteredIcon.innerHTML = '<i class="fa-solid fa-sliders"></i>'; 30311 label.appendChild(filteredIcon); 30312 } 30313 30314 const rightBorder = document.createElement('span'); 30315 rightBorder.className = 'right-border'; 30316 heading.appendChild(rightBorder); 30317 30318 CreateTooltip(heading, col, table); 30319 30320 row_1.appendChild(heading); 30321 } 30322 }); 30323 30324 if (hasChildren) { 30325 allChildrenToggleCell = document.createElement('th'); 30326 allChildrenToggleCell.innerHTML = (allChildrenVisible 30327 ? '<i class="arrow-icon fas fa-chevron-down"></i>' 30328 : '<i class="arrow-icon fas fa-chevron-right"></i>'); 30329 allChildrenToggleCell.addEventListener('click', (e) => { 30330 ToggleAllChildren(e); 30331 }, true); 30332 30333 if (_instanceSettings.ChildRowArrowLeft) { 30334 row_1.prepend(allChildrenToggleCell); 30335 } else { 30336 row_1.appendChild(allChildrenToggleCell); 30337 } 30338} 30339 30340 thead.appendChild(row_1); 30341 } 30342 30343 function GetRenderedRowCounts() { 30344 let rowCounts = { 30345 shown: 0, 30346 total: 0 30347 }; 30348 30349 // Storing the total number of results that could be shown on the screen at one time (before any filters) 30350 if (totalResultsLength === undefined) { 30351 totalResultsLength = dataSource.filter(i => i.IsVisible !== false).length || 0; 30352 } 30353 30354 // Storing the total number of results that should be shown after considering all filters 30355 if (shownResultsLength === undefined) { 30356 shownResultsLength = totalResultsLength; 30357 } 30358 30359 if (_instanceSettings.MaxRenderedRows) { 30360 rowCounts.total = Math.min(_instanceSettings.MaxRenderedRows, totalResultsLength); 30361 } else { 30362 rowCounts.total = shownResultsLength; 30363 } 30364 30365 if (_instanceSettings.PaginationVisible) { 30366 const startIndex = rowCounts.total - ((currentPage - 1) * pageSize); 30367 rowCounts.shown = Math.min(startIndex, pageSize, shownResultsLength); 30368 } else { 30369 rowCounts.shown = Math.min(rowCounts.total, shownResultsLength) || 0; 30370 } 30371 30372 return rowCounts; 30373 } 30374 30375 function DisplayTableContent() { //function to display table content 30376 if (dataSource.length === 0) { 30377 const emptyRow = document.createElement('tr'); 30378 emptyRow.className = 'empty-row'; 30379 30380 const emptyContent = document.createElement('td'); 30381 emptyRow.appendChild(emptyContent); 30382 emptyContent.setAttribute('colspan', columns.filter(col => col.IsVisible === true).length); 30383 emptyContent.innerHTML = _instanceSettings.EmptyDataHtml || 'No records to display'; 30384 30385 tbody.appendChild(emptyRow); 30386 } 30387 30388 let paginatedResults = paginate(dataSource);
30389 paginatedResults.forEach((item, index) => { 30390 const row_x = document.createElement('tr'); 30391 var numLocked = 0; 30392 30393 if (!!item.CssClass) { //css class for item applies to the row 30394 row_x.classList.add(item.CssClass); 30395 } 30396 30397 columns.forEach(col => { 30398 if (!col.IsDraggable || col.IsVisible === true) { 30399 let content = document.createElement('td'); 30400 content.className = col.CssClass || ''; 30401 content.setAttribute('tdkey', col.Key); 30402 const data = item.Data.find(d => d[keyName] === col.Key); 30403 if (data) { 30404 content.innerHTML = data[formatName] != null ? data[formatName] : data[valueName]; 30405 } 30406 if (!col.IsDraggable) { 30407 content.classList.add('is-locked'); 30408 numLocked += 1; 30409 content.classList.add('lock' + numLocked); 30410 } 30411 if (!col.HaveMaxWidth) { 30412 content.classList.add('no-max-width'); 30413 } 30414 row_x.appendChild(content); 30415 } 30416 }); 30417 30418 tbody.appendChild(row_x); 30419 30420 if (hasChildren) { 30421 let arrowColumn = document.createElement('td');
30421 //add another column to the end of the column, with an arrow button 30422 arrowColumn.modalID = `${index}`; 30423 if (_instanceSettings.ChildRowArrowLeft){ 30424 row_x.prepend(arrowColumn) 30425 } 30426 else { 30427 row_x.appendChild(arrowColumn); 30428 } 30429 30430 30431 const childItems = item.ChildItems; 30432 30433 if (childItems !== null && childItems.forEach !== undefined && childItems.length > 0) { 30434 //add arrow button function to collapse next 30435 arrowColumn.className = 'arrow-item'; 30436 arrowColumn.innerHTML = (item.IsChildrenVisible ? '<i class="arrow-icon fas fa-chevron-down"></i>' : '<i class="arrow-icon fas fa-chevron-right"></i>'); 30437 30438 30439 childItems.forEach(childItem => { 30440 var childNumLocked = 0; 30441 let childRow = document.createElement('tr'); //create a table row element 30442 childRow.classList.add(`item-child-${arrowColumn.modalID}`, 'item-child'); 30443 if (!item.IsChildrenVisible) { 30444 childRow.classList.add('card-hidden'); 30445 } 30446 30447 columns.forEach(col => { 30448 if (!col.IsDraggable || col.IsVisible === true) { 30449 let childContent = document.createElement('td'); 30450 childContent.className = 'child-item ' + (col.CssClass || ''); 30451 const childData = childItem.find(d => d[keyName] === col.Key); 30452 if (childData) { 30453 childContent.innerHTML = displayFormat(childData); 30454 } 30455 if (!col.IsDraggable) { 30456 childContent.classList.add('is-locked'); 30457 childNumLocked += 1; 30458 childContent.classList.add('lock' + childNumLocked); 30459 } 30460 childRow.appendChild(childContent); 30461 } 30462 }); 30463 30464 30465 if (_instanceSettings.ChildRowArrowLeft) { 30466 childRow.insertAdjacentHTML('afterbegin', '<td class="child-item"></td>'); 30467 } else { 30468 childRow.insertAdjacentHTML('beforeend', '<td class="child-item"></td>'); 30469 } 30470 30471 tbody.appendChild(childRow); 30472 }); 30473 30474 arrowColumn.addEventListener('click', (e) => { 30475 ToggleItemDropdown(e, 'card-hidden'); 30476 item.IsChildrenVisible = !item.IsChildrenVisible; 30477 }, true); 30478 } 30479 } 30480 }); 30481 } 30482 30483 function DisplayTableFooters() { 30484 const row_foot = document.createElement('tr'); 30485 var numLocked = 0; 30486 columns 30487 .filter(c => (!c.IsDraggable || c.IsVisible)) 30488 .forEach(column => { 30489 const footer = footers.find(f => f[keyName] === column.Key); 30490 const footerCell = document.createElement('td'); 30491 footerCell.className = column.CssClass || ''; 30492 footerCell.innerHTML = footer != null ? (displayFormat(footer)) : "" ; 30493 row_foot.appendChild(footerCell); 30494 if (_instanceSettings.TotalsClass && _instanceSettings.CustomFooterClassKeys.includes(column.Key)) { 30495 footerCell.classList.add(_instanceSettings.TotalsClass); 30496 } 30497 if (!column.IsDraggable) { 30498 footerCell.classList.add('is-locked'); 30499 numLocked += 1; 30500 footerCell.classList.add('lock' + numLocked); 30501 } 30502 }); 30503 30504 if (hasChildren) { 30505 const spacer = document.createElement('td'); 30506 30507 if (_instanceSettings.ChildRowArrowLeft) {
30508 row_foot.prepend(spacer); 30509 } else { 30510 row_foot.appendChild(spacer); 30511 } 30512 } 30513 tfoot.appendChild(row_foot); 30514 } 30515 30516 function footerHasContent(footer) { 30517 if (footer == null) { 30518 return false; 30519 } 30520 const content = displayFormat(footer); 30521 return content != null && content !== ''; 30522 } 30523 30524 function DisplayMobileFooters() { 30525 const mobileFooter = document.createElement('div'); 30526 mobileFooter.classList = 'mobile-footer'; 30527 30528 columns.forEach(column => { 30529 const footer = footers.find(f => f[keyName] === column.Key); 30530 if (!footerHasContent(footer)) { 30531 return; 30532 } 30533 30534 const entry = document.createElement('div'); 30535 entry.classList = 'mobile-footer-entry'; 30536 30537 const label = document.createElement('span'); 30538 label.classList = 'mobile-footer-label'; 30539 label.innerHTML = column.Label; 30540 30541 const value = document.createElement('span'); 30542 value.classList = 'mobile-footer-value'; 30543 value.innerHTML = displayFormat(footer); 30544 30545 entry.appendChild(label); 30546 entry.appendChild(value); 30547 mobileFooter.appendChild(entry); 30548 }); 30549 30550 if (mobileFooter.childElementCount > 0) { 30551 tbody.appendChild(mobileFooter); 30552 } 30553 } 30554 30555 function DisplayMobileHeader() { 30556 const mobileHeaderBar = document.createElement('div'); //item bar for mobile that contains identifying info and button to show more 30557 mobileHeaderBar.classList = 'mobile-header-bar'; 30558 columns.forEach((col, index) => { 30559 if (col.MobileLabel === true) { //add each data element that will be displayed outside the accordion as well 30560 let heading = document.createElement('span'); 30561 heading.className = (col.CssClass || '') + ` mobile-header mEntry${index}`; 30562 heading.setAttribute('data-columnKey', col.Key); 30563 heading.innerHTML = col.Label; 30564 CreateTooltip(heading, col, table); 30565 mobileHeaderBar.appendChild(heading); 30566 } 30567 }); 30568 thead.appendChild(mobileHeaderBar); //add each data entry bar to body 30569 } 30570 30571 function DisplayPagination(){ 30572 const totalCount = (_instanceSettings.MaxRenderedRows) 30573 ? dataSource.filter(r => r.IsVisible).slice(0, _instanceSettings.MaxRenderedRows).length 30574 : dataSource.filter(r => r.IsVisible).length; 30575 30576 const totalPages= Math.ceil(totalCount / pageSize); 30577 let startPage= 1; 30578 let endPage= totalPages; 30579 30580 const setDefaults = () => { 30581 if (totalPages > maxVisiblePages) { 30582 let halfOfMaxPages = maxVisiblePages / 2; 30583 if (currentPage > halfOfMaxPages) { 30584 startPage = currentPage - halfOfMaxPages; 30585 if (startPage > totalPages - maxVisiblePages) 30586 startPage = totalPages - maxVisiblePages + 1; 30587 } 30588 30589 endPage = startPage + maxVisiblePages - 1; 30590 } 30591 }; 30592 30593 const render = () => { 30594 setDefaults(); 30595 30596 if (totalPages > 1) { 30597 createPaginationButton('<', currentPage - 1, false, currentPage > 1); 30598 30599 if (currentPage > 1) { 30600 if (startPage > 1) { 30601 createPaginationButton('1', 1, currentPage === 1); 30602 } 30603 30604 if (startPage >= 2) { 30605 createPaginationButton('...', null); 30606 } 30607 } 30608 30609 for (let i = startPage; i <= endPage && totalPages > 1; i++) { 30610 createPaginationButton(i, i, i === currentPage); 30611 } 30612 30613 if (currentPage < totalPages) { 30614 if (endPage <= totalPages - 1) { 30615 createPaginationButton('...', null); 30616 } 30617 30618 if (endPage < totalPages) { 30619 createPaginationButton(totalPages, totalPages, currentPage === totalPages); 30620 } 30621 } 30622 30623 createPaginationButton('>', currentPage + 1, false, currentPage < totalPages); 30624 } 30625 }; 30626 30627 const createPaginationButton = (text, page, isActive = false, isEnabled = true) => { 30628 let button= document.createElement('button'); 30629 button.textContent = text; 30630 button.className = isActive ? 'active' : ''; 30631 30632 if (!page || isActive || !isEnabled) { 30633 button.setAttribute("disabled", "disabled"); 30634 } 30635 else { 30636 button.addEventListener('click', (event)=> { 30637 event.preventDefault(); 30638 table.scrollTo({top: 0, behavior: 'smooth'}); 30639 window.scrollTo({top: table.getBoundingClientRect().top + window.pageYOffset, behavior: 'smooth'}); 30640 currentPage = page; 30641 DrawTable(true); 30642 }); 30643 } 30644 30645 pagination.appendChild(button); 30646 }; 30647 30648 render(); 30649 } 30650
30651 function DisplayMobileTable() { 30652 dataSource.forEach((item, index) => { 30653 if (item.IsVisible !== false) { 30654 const itemMobileEntry = document.createElement('div'); //item bar for mobile that contains identifying info and button to show more 30655 itemMobileEntry.classList = 'mobile-entry'; 30656 var numLocked = 0; 30657 const accordionArrow = document.createElement('span'); //accordion toggle visibility button 30658 accordionArrow.classList = 'accordion-arrow'; 30659 accordionArrow.modalID = `${index}`; 30660 accordionArrow.innerHTML = '<i class="arrow-icon fas fa-chevron-right"></i>'; 30661 const itemAccordion = document.createElement('div'); //create dropdown modal, set to hidden 30662 itemAccordion.classList = 'item-accordion accordion-hidden'; 30663 itemAccordion.id = `${index}-item-accordion`; 30664 30665 columns.forEach((col, index) => { 30666 if (col.MobileLabel === true) { //add each data element that will be displayed outside the accordion as well 30667 let content = document.createElement('span'); 30668 content.className = (col.CssClass || '') + ` mobile-label mEntry${index}`; 30669 content.setAttribute('tdkey', col.Key); 30670 const data = item.Data.find(d => d[keyName] === col.Key); 30671 if (data) { 30672 content.innerHTML = displayFormat(data); 30673 } 30674 30675 if (!col.IsDraggable) { 30676 content.classList.add('is-locked'); 30677 numLocked += 1; 30678 content.classList.add('lock' + numLocked); 30679 } 30680 itemMobileEntry.appendChild(content); 30681 } 30682 if (col.MobileEntry === true && col.MobileLabel !== true) { 30683 let accordionEntry = document.createElement('div'); //each row of data in the accordion 30684 accordionEntry.classList = 'accordion-entry'; 30685 let accordionLabel = document.createElement('span'); //column label of accordion data 30686 accordionLabel.classList = 'accordion-label'; 30687 accordionLabel.innerHTML = (col.Label.length > 0 ? col.Label + ': ' : ' '); 30688 let accordionContent = document.createElement('span'); //item's data within accordion 30689 accordionContent.classList = 'accordion-data'; 30690 accordionContent.setAttribute('tdkey', col.Key); 30691 const data = item.Data.find(d => d[keyName] === col.Key); 30692 if (data) { 30693 accordionContent.innerHTML = displayFormat(data); 30694 } 30695 itemAccordion.appendChild(accordionEntry); 30696 accordionEntry.appendChild(accordionLabel); 30697 accordionEntry.appendChild(accordionContent); 30698 } 30699 }); 30700 30701 itemMobileEntry.appendChild(accordionArrow); //add item bar to row_x 30702 accordionArrow.addEventListener('click', (e) => ToggleMobileDropdown(e, 'accordion-hidden'), true);//event listener to dropdown button: when clicked toggle dropdown modal visibility (via class change) 30703 tbody.appendChild(itemMobileEntry); //add each data entry bar to body 30704 tbody.appendChild(itemAccordion); //add hidden accordion following the bar 30705 } 30706 }); 30707 } 30708 30709 function AlignMobileHeader() { 30710 const mobileEntries = [...table.querySelectorAll('.mobile-header,.mobile-label')]; 30711 for (let entry = 0; entry <= mobileEntries.length; entry++) { 30712 let entryCol = [...table.querySelectorAll(`.mEntry${entry}`)]; 30713 let maxwidth = 0; 30714 entryCol.forEach(element => { 30715 maxwidth = Math.max(maxwidth, element.offsetWidth);
30716 }); 30717 entryCol.forEach(element => { 30718 element.style.width = maxwidth + 'px'; 30719 element.style.paddingRight = '15px'; 30720 }); 30721 } 30722 } 30723 30724 function ToggleMobileDropdown(event, accordionClass) { 30725 var itemAccordionSelected = document.getElementById(`${event.target.modalID}-item-accordion`); 30726 if (itemAccordionSelected.classList.contains(accordionClass)) {//if accordion is hidden 30727 itemAccordionSelected.classList.remove(accordionClass); //set accordion to revealed 30728 event.target.innerHTML = '<i class="arrow-icon fas fa-chevron-down"></i>'; 30729 } 30730 else { 30731 itemAccordionSelected.classList.add(accordionClass);//set accordion to hidden 30732 event.target.innerHTML = '<i class="arrow-icon fas fa-chevron-right"></i>'; 30733 } 30734 } 30735 30736 function ToggleItemDropdown(event, childClass) { 30737 var itemChildrenSelected = [...table.querySelectorAll(`.item-child.item-child-${event.target.modalID}`)]; 30738 if (itemChildrenSelected !== null) { 30739 itemChildrenSelected.forEach(item => { 30740 if (item.classList.contains(childClass)) {//if child is hidden 30741 item.classList.remove(childClass); //set child to revealed 30742 event.target.innerHTML = '<i class="arrow-icon fas fa-chevron-down"></i>'; 30743 } 30744 else { 30745 item.classList.add(childClass);//set child to hidden 30746 event.target.innerHTML = '<i class="arrow-icon fas fa-chevron-right"></i>'; 30747 } 30748 }); 30749 } 30750 } 30751 30752 function ToggleAllChildren() { 30753 if (!hasChildren) 30754 return; 30755 30756 const childClass = 'card-hidden'; 30757 const itemArrowSelected = $(wrapper).find('.arrow-item'); 30758 const itemChildrenSelected = $(wrapper).find('.item-child'); 30759 30760 if (itemChildrenSelected !== null) { 30761 if (!allChildrenVisible) { 30762 itemChildrenSelected.removeClass(childClass) 30763 itemArrowSelected.html('<i class="arrow-icon fas fa-chevron-down"></i>'); 30764 } 30765 else { 30766 itemChildrenSelected.addClass(childClass); 30767 itemArrowSelected.html('<i class="arrow-icon fas fa-chevron-right"></i>'); 30768 } 30769 30770 allChildrenVisible = !allChildrenVisible; 30771 dataSource.forEach(i => i.IsChildrenVisible = allChildrenVisible); 30772 allChildrenToggleCell.innerHTML = allChildrenVisible 30773 ? '<i class="arrow-icon fas fa-chevron-down"></i>' 30774 : '<i class="arrow-icon fas fa-chevron-right"></i>'; 30775 } 30776 } 30777 30778 //sort by selected column, ascending or descending 30779 function SortTable(columnInput, forceDescending = null) { 30780 if (isDataSourceModified) { 30781 $.fn.modalAlert.open({ content: 'Sorting edited data is not supported' }); 30782 return; 30783 } 30784 30785 const wasDescending = columnDescending; 30786 30787 if(!dataSource.length || !columnInput || !columns.some(j => j.Key === columnInput)){ 30788 sortedColumn = null; 30789 return; 30790 } 30791 30792 if (columnInput === sortedColumn) { //if column was also last sorted 30793 columnDescending = forceDescending !== null ? forceDescending : !columnDescending; 30794 } 30795 else { //if a new column was clicked 30796 columnDescending = forceDescending !== null ? forceDescending : false; 30797 } 30798 30799 const justReversed = columnInput === sortedColumn && columnDescending === !wasDescending; 30800 const isAscending = !columnDescending; 30801 30802 // Optimization: Cache sorted results for instant repeated sorts 30803 if (sortCache.column === columnInput && 30804 sortCache.ascending === isAscending && 30805 sortCache.sortedData && 30806 !justReversed) { 30807 dataSource = sortCache.sortedData; 30808 sortedColumn = columnInput; 30809 return; 30810 } 30811 30812 if(!justReversed) 30813 { 30814 // Optimization: Shallow copy instead of structuredClone (10x faster) 30815 dataSource = dataSourceOrig.map(row => ({ ...row })); 30816 30817 const timeZoneCodes = ['EST', 'CST', 'MST', 'PST', 'Ar
30817izona', 'HST']; 30818 let dateFormats = [ 30819 moment.ISO_8601, 30820 "M/D/YY", 30821 ...timeZoneCodes.map(tz => `M/D/YY h:ma [${tz}]`) 30822 ]; 30823 let columnValueType = columns.find(x => x.Key == columnInput).ValueType 30824 30825 const extractAndNormalizeValue = (row) => { 30826 // Optimization: Use pre-computed values if available (O(1) lookup) 30827 if (row._sortValues && row._sortValues[columnInput] !== undefined) { 30828 return row._sortValues[columnInput]; 30829 } 30830 30831 // Fallback: compute on-the-fly if pre-computed value not available 30832 let match = row.Data.find(j => j[keyName] === columnInput); 30833 let value = match?.[valueName]; 30834 30835 if (value === null && match?.[formatName] !== undefined) { 30836 value = match[formatName]; 30837 } 30838 30839 if (value === null || value === undefined) 30840 value = ''; 30841 30842 //Col Types: String, Bool, NullableBool, Number, Date, UnSet 30843 switch (columnValueType) { 30844 case "String": 30845 return value.toString().toLowerCase().trim(); 30846 case "Bool": 30847 //do nothing to bools since they dont need to be converted 30848 return value; 30849 case "NullableBool": 30850 return value != "" ? value : false; 30851 case "Number": 30852 return value != "" ? +(value) : 0; 30853 case "Date": 30854 return value != "" ? moment(value, dateFormats, true).valueOf() : moment(1900).valueOf(); 30855 case "NumberString": 30856 const firstNumRegex = /^\d+|\d+\b|\d+(?=\w)/g; 30857 const matchChange = String(value).match(firstNumRegex); 30858 return value != "" ? + (matchChange != null ? matchChange[0] : 0) : 0; 30859 default: 30860 if (moment(value, dateFormats, true).isValid()) { 30861 return value != "" ? moment(value, dateFormats, true).valueOf() : moment(1900).valueOf(); 30862 } 30863 else if (/^-?\d+$/.test(value)) { 30864 return value != "" ? +(value) : 0; 30865 } 30866 else if (typeof (value) != 'boolean') { 30867 return value.toString().toLowerCase().trim(); 30868 } 30869 return value; 30870 } 30871 }; 30872 30873 // Optimization: Schwartzian transform - extract values once before sorting (runs N times instead of N log N) 30874 const decorated = dataSource.map((row, index) => ({ 30875 row, 30876 sortValue: extractAndNormalizeValue(row), 30877 originalIndex: index 30878 })); 30879 30880 // Optimization: Use direct numeric subtraction for numeric columns (faster than comparison) 30881 const isNumeric = columnValueType === "Number" || columnValueType === "NumberString"; 30882 30883 decorated.sort((a, b) => { 30884 if (a.sortValue === b.sortValue) 30885 return a.originalIndex - b.originalIndex; 30886 30887 if (isNumeric) { 30888 return a.sortValue - b.sortValue; 30889 } 30890 30891 return a.sortValue > b.sortValue ? 1 : -1; 30892 }); 30893 30894 dataSource = decorated.map(d => d.row); 30895 30896 // Cache the sorted result for future use 30897 sortCache = { 30898 column: columnInput, 30899 ascending: isAscending, 30900 sortedData: dataSource.map(row => ({ ...row })) 30901 }; 30902 } 30903 30904 if (columnDescending || justReversed) 30905 { 30906 dataSource = dataSource.reverse(); 30907 } 30908 30909 sortedColumn = columnInput; 30910 } 30911 30912 function GetDragAfterElement(container, x, direction) { 30913 const draggableElements = [...container.querySelectorAll('[draggable=true]:not(.dragging)')] 30914 return draggableElements.reduce((closest, child) => { 30915 const box = child.getBoundingClientRect(); 30916 const offset = (direction === 'vertical' ? x - box.top - box.height / 2 : x - box.left - box.width / 2); 30917 30918 if (offset < 0 && offset > closest.offset) { 30919 return { offset: offset, element: child } 30920 } 30921 else { 30922 return closest; 30923 } 30924 }, { offset: Number.NEGATIVE_INFINITY }).element 30925 } 30926 30927 function MoveColumn(movedColumn, positionInsert, columnList) { 30928 if (positionInsert == undefined) { 30929 positionInsert = null; 30930 } 30931 if (positionInsert !== undefined) { 30932 let columnDragging = columnList.find(c => c.Key === movedColumn.getAttribute('data-columnKey')); //get draggable's old position 30933 columnList.forEach(col => { 30934 if (col.Order > columnDragging.Order) { 30935 col.Order -= 1; 30936 } 30937 }); 30938 if (positionInsert === null) {//if insertion point is at the end of the list 30939 columnList.find(c => c.Key === movedColumn.getAttribute('data-columnKey')).Order = columnList.length - 1; //set it to the last item 30940 } 30941 else { 30942 let insertJustBefore = columnList.find(c => c.Key === positionInsert.getAttribute('data-columnKey')); //get column to insert just before 30943 columnDragging.Order = insertJustBefore.Order; 30944 columnList.forEach(col => { //re-add 1 to every element with order >= than the dragged Column's new 30945 if (col.Order >= columnDragging.Order && col.Key !== columnDragging.Key) { 30946 col.Order++ 30947 } 30948 }); 30949 } 30950 } 30951 else { 30952 console.warn('invalid position'); 30953 } 30954 } 30955 30956 function DrawTopNav() { 30957 const topNav = document.createElement('div'); 30958 topNav.className = 'top-nav'; 30959 30960 headerDiv = document.createElement('div'); 30961 headerDiv.className = "header-div"; 30962 topNav.appendChild(headerDiv); 30963 30964 heading = document.createElement('h2'); 30965 updateTitle(); 30966 headerDiv.appendChild(heading); 30967 30968 if (_instanceSettings.HeaderTooltip !== undefined) 30969 { 30970 const headerTooltip = document.createElement('i') 30971 headerTooltip.className = 'fas fa-question-circle header-tooltip'; 30972 headerTooltip.title = _instanceSettings.HeaderTooltip; 30973 headerTooltip.style.marginLeft = '5px'; 30974 headerTooltip.addEventListener('mouseover', (e) => ShowTooltip(e, wrapper)); 30975 headerTooltip.addEventListener('mouseout', (e) => HideTooltip(e)); 30976 headerDiv.appendChild(headerTooltip); 30977 } 30978 if (_instanceSettings.SimpleHeader != true) { 30979 controlContainer = document.createElement('div'); 30980 controlContainer.className = 'controls'; 30981 30982 if (_instanceSettings.SearchBarVisible){ 30983 CreateSearchBar(controlContainer, _instanceSettings, _title); 30984 } 30985 30986 //create custom menu bar buttons 30987 _instanceSettings.CustomTopNavButtonList.forEach(b => { //for each custom button 30988 var customButton = document.createElement('button');//create a button 30989 customButton.type = 'button'; 30990 customButton.title = b.Title; 30991 if (b.Id) { 30992 customButton.id = b.Id;
30993 } 30994 customButton.className = b.CssClass || 'ForwardButtonShort menu-button'; 30995 if (b.EnabledWhenItemsChecked === true) { 30996 customButton.classList.add('checkbox-button'); 30997 customButton.disabled = true; 30998 } 30999 customButton.innerHTML = b.InnerHtml; 31000 if (b.ClientScript != null) { 31001 customButton.addEventListener('click', () => eval(b.ClientScript)); 31002 } 31003 else { 31004 customButton.addEventListener('click', () => { 31005 const submit = () => { 31006 CustomMenuButtonPostBack({ 31007 Key: b.Key, 31008 Value: b.Value 31009 }); 31010 }; 31011 31012 if (b.ShowDownloadWarning) { 31013 $.fn.modalConfirm.open({ 31014 title: 'Privacy Restricted', 31015 content: 'In order to protect the privacy of our clients, an administrator will be notified if you export this content. Agree to continue?', 31016 confirm: () => { 31017 submit(); 31018 } 31019 }); 31020 } 31021 else if (!!b.ConfirmationMessage) { 31022 $.fn.modalConfirm.open({ 31023 content: b.ConfirmationMessage, 31024 confirm: submit 31025 }); 31026 } 31027 else { 31028 submit(); 31029 } 31030 }); 31031 } 31032 controlContainer.appendChild(customButton); 31033 }); 31034 31035 //add item button 31036 if (_instanceSettings.AddItemButtonIsVisible) { 31037 addItem = document.createElement('button'); 31038 addItem.title = (_instanceSettings.AddItemButtonTitle ? _instanceSettings.AddItemButtonTitle : 'Add Item'); 31039 addItem.type = 'button'; 31040 addItem.className = 'ForwardButton menu-button'; 31041 if (_instanceSettings.AddItemButtonClientScript) { 31042 addItem.addEventListener('click', () => eval(_instanceSettings.AddItemButtonClientScript)); 31043 } 31044 else { 31045 addItem.addEventListener('click', () => addItemPostBack()); 31046 } 31047 addItem.innerHTML = '<i class="fas fa-plus"></i>'; 31048 if (!_instanceSettings.AddItemButtonIsEnabled) { 31049 addItem.disabled = true; 31050 } 31051 controlContainer.appendChild(addItem); 31052 } 31053 31054 if (_instanceSettings.ShowCustomizeButton){ 31055 //customize table button 31056 customizeTable = document.createElement('button'); 31057 customizeTable.title = "Customize Table"; 31058 customizeTable.type = "button"; 31059 evaluateCustomizeBtnClass(); 31060 customizeTable.addEventListener('click', () => { 31061 ToggleMenuModal(false); 31062 CreateColumnPanel(columns, sortedColumn, document.getElementById('SortableTableModal'), columnFilters); 31063 $.fn.modalElement.open({ target: `#${wrapper.id} .sortable-table-modal` }); 31064 }); 31065 customizeTable.innerHTML = "<i class=\"fas fa-list\"></i>"; 31066 controlContainer.appendChild(customizeTable); 31067 } 31068 31069 if (_instanceSettings.ExcelExportVisible && dataSource.length > 0) { 31070 const exportExcelButton = document.createElement('button'); 31071 exportExcelButton.title = 'Export To Excel'; 31072 exportExcelButton.type = 'button'; 31073 exportExcelButton.className = 'ForwardButton menu-button'; 31074 exportExcelButton.innerHTML = '<i class="fa fa-file-export"></i>'; 31075 31076 if (_instanceSettings.ShowDownloadWarning) { 31077 exportExcelButton.setAttribute('download-warning-trigger', ''); 31078 } 31079 31080 exportExcelButton.addEventListener('click', () => { 31081 ToggleMenuModal(false); 31082 ExportDataToExcel(); 31083 }); 31084 31085 controlContainer.appendChild(exportExcelButton); 31086 } 31087 31088 CreateMenuModal(controlContainer); 31089 31090 if (_instanceSettings.ShowOptionsButton && _instanceSettings.CustomButtonList.length > 0) { 31091 //table options button 31092 tableOptions = document.createElement('button'); 31093 tableOptions.title = 'More Options'; 31094 tableOptions.type = 'button'; 31095 tableOptions.className = 'ForwardButton menu-button'; 31096 tableOptions.addEventListener('click', (e) => { 31097 ToggleMenuModal(); 31098 }); 31099 tableOptions.innerHTML = '<i class="fas fa-ellipsis-v"></i>'; 31100 controlContainer.appendChild(tableOptions); 31101 } 31102 31103 if (!dataSource.length && tableOptions) tableOptions.disabled = true; 31104 31105 topNav.appendChild(controlContainer); 31106 } 31107 wrapper.appendChild(topNav); 31108
31109 enabledWhenCheckedButtons = [...topNav.querySelectorAll('.checkbox-button')]; 31110 31111 } 31112 31113 function evaluateCustomizeBtnClass() { 31114 if (customizeTable) { 31115 const invert = columns.filter(c => !!c.IsVisible != !!c.IsClientVisible).length > 0 || columnFilters.some(c => c.text.length > 0); 31116 customizeTable.className = `ForwardButton menu-button ${(invert ? "inverted-menu-button" : "")}`; 31117 } 31118 } 31119 31120 function updateTitle() { 31121 const counts = GetRenderedRowCounts(); 31122 const formatter = new Intl.NumberFormat(); 31123 31124 let recordsString = ''; 31125 if (counts.total !== counts.shown) { 31126 recordsString = `${formatter.format(counts.shown)}/${formatter.format(counts.total)} Records`; 31127 } else { 31128 recordsString = `${formatter.format(counts.total)} Record${counts.total === 1 ? '' : 's'}`; 31129 } 31130 31131 const selectedRecords = Object.keys(checkboxStatus).filter(key => checkboxStatus[key] === true); 31132 31133 if (selectedRecords.length > 0) { 31134 recordsString += ` - ${selectedRecords.length} Selected`; 31135 } 31136 31137 heading.innerHTML = `${_title} <span class='record-count'>${recordsString}</span>`; 31138 31139 let span = heading.querySelector('span.record-count'); 31140 if (!span) { 31141 return; 31142 } 31143 31144 const container = span.closest('.sortable-table'); 31145 if (!container) { 31146 return; 31147 } 31148 31149 const hiddenField = document.getElementById(container.id +'_SelectedIdsHidden'); 31150 if (hiddenField) { 31151 hiddenField.value = selectedRecords.join(","); 31152 } 31153 } 31154 31155 function addItemPostBack() { 31156 __doPostBack(`${wrapper.id}$AddItemEvent`, ''); 31157 } 31158 31159 function CreateSearchBar(parentElement) { 31160 let searchTimeout = null; 31161 var searchDiv = document.createElement('span'); 31162 searchDiv.className = 'table-search-container'; 31163 parentElement.appendChild(searchDiv); 31164 31165 var searchBar = document.createElement('input'); 31166 searchBar.type = 'text'; 31167 searchBar.className = 'table-search-bar'; 31168 searchBar.id = `${wrapper.id}search`; 31169 searchBar.placeholder = `Search ${_instanceSettings.SearchBarPlaceholder || _title || 'Table'}`; 31170 searchBar.value = _instanceSettings.SearchText || ''; 31171 31172 if (dataSource.length < 2 && !_instanceSettings.SearchIsPostBack || isDataSourceModified) { 31173 searchBar.disabled = true; 31174 } 31175 31176 searchDiv.appendChild(searchBar); 31177 searchBar.addEventListener("keydown", function (event) { 31178 if (event.keyCode === 13) { 31179 event.preventDefault(); 31180 } 31181 }); 31182 var searchIcon = document.createElement('i'); 31183 searchIcon.className = 'search-bar-icon fas fa-search'; 31184 searchIcon.style.pointerEvents = 'none'; 31185 searchDiv.appendChild(searchIcon); 31186 31187 if (!!_instanceSettings.SearchIsPostBack) { 31188 searchBar.onkeyup = ((event) => { 31189 if (event.keyCode === 13) { 31190 event.preventDefault(); 31191 searchBarPostBack(event.target.value); 31192 } 31193 }); 31194 } 31195 else { 31196 clearTimeout(searchTimeout); 31197 searchBar.onkeyup = (() => { 31198 searchTimeout = setTimeout(() => BasicSearchFilter(), 400); 31199 }); 31200 } 31201 31202 var advSearchButton = document.createElement('button'); 31203 advSearchButton.title = 'Advanced Search Options'; 31204 advSearchButton.type = 'button'; 31205 advSearchButton.className = 'ForwardButton menu-button ' + _instanceSettings.AdvanceSearchButtonCssClass; 31206 advSearchButton.innerHTML = '<i class="fas fa-sliders-h"/>'; 31207 parentElement.appendChild(advSearchButton); 31208 31209 (_instanceSettings.AdvanceSearchButtonSelector ? //check if adv search is enabled and either 31210 advSearchButton.onclick = (() => { $.fn.modalElement.open({ target: _instanceSettings.AdvanceSearchButtonSelector }); }) : //set button to open adv search menu 31211 advSearchButton.style.display = 'none'); //hide adv search button 31212 } 31213 31214 function GetInnerTextOfHtml(html) { 31215 if (html === null) 31216 return null; 31217 31218 if (typeof (html) === 'boolean') 31219 return html ? "â" : ""; 31220 31221 if (typeof (html) === 'number') 31222 return html.toString(); 31223 31224 if (typeof (html) === 'object') 31225 return JSON.stringify(html); 31226 31227 if (typeof (html) !== 'string') 31228 return ''; 31229 31230 if (html.trim().toString().indexOf('<') === 0) { 31231 try { 31232 const $element = $(html); 31233 if ($element.is('input') && $element.prop('type') === 'text') { 31234 return $element.val(); 31235 } 31236 if ($element.is('.icon-circle')) { 31237 return $element.find('i').attr('title'); 31238 } 31239 const $icon = $element.find('.icon-circle'); 31240 if ($icon.length === 1) { 31241 return $icon.find('i').attr('title'); 31242 } 31243 31244 const $i = $element.find('i[title]'); 31245 if ($i.length === 1) { 31246 return $i.attr('title'); 31247 } 31248 31249 return $(`<div>${html}</div>`).filter(':not(button)').text().trim(); 31250 } 31251 catch { } // pass 31252 } 31253 31254 const element = document.createElement('div'); 31255 element.innerHTML = html; 31256 return element.textContent.toString(); 31257 } 31258 31259 function BasicSearchFilter() { 31260 [...table.querySelectorAll('input[type=checkbox]')] 31261 .filter(c => 31262 c.classList.contains('sortableCheckbox') || 31263 (c.value && c.value !== 'on') 31264 ) 31265 .forEach(c => checkboxStatus[c.value] = c.checked); 31266 31267 const searchString = document.getElementById(`${wrapper.id}search`).value.toUpperCase(); 31268 const searchStringSplit = searchString.split(' ').map(e => e.toUpperCase().trimEnd()); 31269 currentPage = 1; //resetting table to page 1 when searching 31270 31271 showFooter = true; 31272 dataSource.forEach(item => item.IsVisible = true); 31273 31274 if (searchString !== '') { 31275 const visibleColumns = columns 31276 .filter(column => column.IsVisible && !dataSource.some(item => item.Data.some(d => d[keyName] === column.Key && d[modifiedName]))); 31277 31278 dataSource.forEach(item => { 31279 const searchableTerms = []; 31280 31281 visibleColumns 31282 .forEach(column => { 31283 const col = item.Data.find(d => d[keyName] === column.Key); 31284 31285 if (col && !!col[formatName]) { 31286 const formatted = item.Data.find(d => d[keyName] === column.Key)[formatName]; 31287 searchableTerms.push(GetInnerTextOfHtml(formatted)); 31288 } 31289 else if (col && !!col[valueName]) { 31290 const val = item.Data.find(d => d[keyName] === column.Key)[valueName]; 31291 if (val === false || val === true) // don't match on bools which are almost always formatted 31292 return null; 31293 searchableTerms.push(val.toString()); 31294 } 31295 if (item.ChildItems !== undefined) {
31296 item.ChildItems.forEach(child => { 31297 const childcol = child.find(d => d[keyName] === column.Key); 31298 31299 if (childcol && !!childcol[formatName]) { 31300 const formatted = child.find(d => d[keyName] === column.Key)[formatName]; 31301 searchableTerms.push(GetInnerTextOfHtml(formatted)); 31302 } 31303 else if (childcol && !!childcol[valueName]) { 31304 const val = child.find(d => d[keyName] === column.Key)[valueName]; 31305 if (val === false || val === true) // don't match on bools which are almost always formatted 31306 return null; 31307 searchableTerms.push(val.toString()); 31308 } 31309 }); 31310 } 31311 }); 31312 31313 const isFound = TermIsFound(searchableTerms, searchStringSplit); 31314 31315 showFooter = (!isFound ? false : showFooter) 31316 item.IsVisible = isFound; //if found is false (you didn't find any least one) set item's filtered to invisible 31317 }); 31318 } 31319 31320 FilterTableColumns(); 31321 31322 updateTitle(); 31323 DrawTable(true); 31324 } 31325 31326 function TermIsFound(_searchableTerms, _searchStringSplit) { 31327 const found = {}; 31328 return _searchableTerms 31329 .filter(term => term !== '' && typeof (term) === 'string') 31330 .some(term => { 31331 let isMatch; 31332 _searchStringSplit.forEach(e => { 31333 e = e.toUpperCase(); 31334 if (term.toUpperCase().indexOf(e) > -1) { 31335 found[e] = 1; 31336 isMatch = true; 31337 } 31338 }); 31339 31340 if (isMatch) { 31341 // if every word in the split search query is found in our found array (any column in a single row) 31342 const foundContainsSearch = _searchStringSplit.every(str => str in found); 31343 if (foundContainsSearch) return true; 31344 } 31345 31346 return false; 31347 }); 31348 } 31349 31350 function TermEquals(_searchableTerms, _searchString) { 31351 return _searchableTerms 31352 .filter(term => term !== '' && typeof (term) === 'string') 31353 .some(term => { 31354 return term.toUpperCase() == _searchString.toUpperCase(); 31355 }); 31356 } 31357 31358 function TermNotEquals(_searchableTerms, _searchString) { 31359 if (!_searchableTerms.length) return false; 31360 31361 return _searchableTerms 31362 .filter(term => typeof (term) === 'string') 31363 .every(term => term.toUpperCase() !== _searchString.toUpperCase()); 31364 } 31365 31366 function TermCompare(_value, _searchString, termGreaterThan) { 31367 var searchVal = parseInt(_searchString); 31368 return termGreaterThan ? _value > searchVal : _value < searchVal; 31369 } 31370 31371 function BoolTerm(_searchableTerms, _searchBool) { 31372 return _searchableTerms 31373 .filter(term => term !== '') 31374 .some(term => { 31375 return term === _searchBool; 31376 }); 31377 } 31378 31379 const searchBarPostBack = (searchSettings) => 31380 __doPostBack(`${wrapper.id}$SearchBarText`, JSON.stringify(searchSettings)); 31381 31382 function CreateMenuModal(parentButton) { 31383 if (_instanceSettings.CustomButtonList.length === 0) 31384 return; 31385 31386 menuModal = document.createElement('span'); 31387 menuModal.id = `${wrapper.id}-menu-modal`; 31388 menuModal.className = 'menu-modal'; 31389 menuModal.innerHTML = ''; 31390 menuModal.hidden = true; 31391 parentButton.appendChild(menuModal); 31392 31393 _instanceSettings.CustomButtonList.forEach(b => { //for each custom button 31394 let customButton = document.createElement('button');//create a button 31395 customButton.type = 'button'; 31396 customButton.title = b.Title || ''; 31397 customButton.className = b.CssClass || 'ForwardButton'; 31398 customButton.innerHTML = b.InnerHtml; 31399 31400 if (b.Id) { 31401 customButton.id = b.Id;
31402 } 31403 31404 if (b.ClientScript != null) { 31405 customButton.addEventListener('click', () => { 31406 eval(b.ClientScript); 31407 }); 31408 } 31409 else { 31410 customButton.addEventListener('click', () => { 31411 const submit = () => CustomMenuButtonPostBack({ 31412 Key: b.Key, 31413 Value: b.Value 31414 }); 31415 31416 31417 if (b.ShowDownloadWarning) { 31418 $.fn.modalConfirm.open({ 31419 title: 'Privacy Restricted', 31420 content: 'In order to protect the privacy of our clients, an administrator will be notified if you export this content. Agree to continue?', 31421 confirm: () => { 31422 submit(); 31423 } 31424 }); 31425 } 31426 else if (!!b.ConfirmationMessage) { 31427 $.fn.modalConfirm.open({ 31428 content: b.ConfirmationMessage, 31429 confirm: () => { 31430 submit() 31431 } 31432 }); 31433 } 31434 else { 31435 submit(); 31436 } 31437 31438 ToggleMenuModal(false); 31439 }); 31440 } 31441 31442 menuModal.appendChild(customButton); 31443 }); 31444 31445 31446 } 31447 31448 function ToggleMenuModal(state) { 31449 if (menuModal) { 31450 menuModal.hidden = (state !== undefined ? !state : !menuModal.hidden); 31451 (menuModal.hidden !== true ? window.addEventListener('click', CloseMenuModal) : window.removeEventListener('click', CloseMenuModal)) 31452 } 31453 } 31454 31455 function CloseMenuModal(event) { 31456 if (!menuModal.hidden && !menuModal.contains(event.target) && !tableOptions.contains(event.target)) { 31457 ToggleMenuModal(false); 31458 } 31459 } 31460 31461 function fixOrder(_columns) { 31462 let lastOrder = -1; 31463 let orderChanged = false; 31464 let i; 31465 31466 for (i = 0; i < _columns.length; i++){ 31467 const col = _columns[i]; 31468 31469 if (lastOrder === col.Order) { 31470 orderChanged = true; 31471 break; 31472 } 31473 lastOrder = col.Order; 31474 } 31475 31476 if (orderChanged) { 31477 for (let j = i; j < _columns.length; j++) { 31478 _columns[j].Order++; 31479 } 31480 } 31481 } 31482 31483 function CreateColumnPanel(_columns, sortedColumnPending, modalPanel, _columnFilters = null) { 31484 let modalColumnFilters = structuredClone(_columnFilters); 31485 let modalColumnsPending = structuredClone(_columns); 31486 modalColumnsPending.sort((a, b) => a.Order > b.Order ? 1 : -1); 31487 31488 fixOrder(modalColumnsPending); 31489 31490 if (!modalPanel) { 31491 modalPanel = document.createElement('div'); 31492 modalPanel.className = 'sortable-table-modal'; 31493 modalPanel.id = 'SortableTableModal'; 31494 modalPanel.hidden = true; 31495 wrapper.appendChild(modalPanel); 31496 } 31497 else { 31498 modalPanel.innerHTML = ''; 31499 } 31500 31501 const panelHeader = document.createElement('h2'); 31502 panelHeader.innerHTML = 'Order and Hide Columns'; 31503 modalPanel.appendChild(panelHeader); 31504 31505 const selectMenu = document.createElement('ul'); 31506 selectMenu.classList.add('plain-list'); 31507 selectMenu.addEventListener('dragover', e => { 31508 e.preventDefault(); 31509 afterElementModal = GetDragAfterElement(selectMenu, e.clientY, 'vertical'); //get element of just-before 31510 }); 31511 31512 modalColumnsPending.forEach(col => { 31513 if (col.IsDraggable) { 31514 const menuItem = document.createElement('li'); 31515 menuItem.setAttribute('data-columnKey', col.Key); 31516 menuItem.classList.add('menu-item'); 31517 menuItem.classList.add('flex'); 31518 menuItem.setAttribute('draggable', 'true'); 31519 menuItem.addEventListener('dragstart', () => { 31520 menuItem.classList.add('dragging'); 31521 }); 31522 menuItem.addEventListener('dragend', e => { 31523 menuItem.classList.remove('dragging'); 31524 MoveColumn(menuItem, afterElementModal, modalColumnsPending); 31525 CreateColumnPanel(modalColumnsPending, sortedColumnPending, $(e.target).closest('.sortable-table-modal').get(0), modalColumnFilters); 31526 }); 31527 31528 if (!col.InputRequired) { 31529 const visSpan = document.createElement('span'); 31530 visSpan.className = 'vis-button-container'; 31531 const visTemplate = document.createElement('button'); 31532 visTemplate.type = 'button'; 31533 visTemplate.className = 'column-panel-toggle RoundButton' + (col.IsVisible ? ' is-visible' : ''); 31534 visTemplate.innerHTML = `<i class=${(col.IsVisible ? '"fas fa-eye"' : '"fas fa-eye-slash"')}></i>`; 31535 visTemplate.addEventListener('click', (e) => { 31536 (visTemplate.classList.contains('is-visible') ? visTemplate.classList.remove('is-visibles') : visTemplate.classList.add('is-visible')) 31537 modalColumnsPending.forEach(i => i.IsVisible = (i.Key === col.Key ? !i.IsVisible : i.IsVisible)); 31538 CreateColumnPanel(modalColumnsPending, sortedColumnPending, $(e.target).closest('.sortable-table-modal').get(0), modalColumnFilters); 31539 }); 31540 visSpan.append(visTemplate) 31541 menuItem.append(visSpan); 31542 } else { 31543 // replaces the visibility button width 31544 const span = document.createElement('span'); 31545 span.className = 'vis-button-container'; 31546 menuItem.append(span); 31547 } 31548 31549 const colTemplate = document.createElement('div'); 31550 colTemplate.classList.add('modal-entry'); 31551 (col.isSelected ? colTemplate.classList.add('selected') : ""); 31552 colTemplate.innerHTML = '<label class="column-panel-option">' 31553 + (col.InputRequired ? "<span>" : "") 31554 + col.Label 31555 + (col.InputRequired ? "<span style='color: red;'> *</span></span>" : "") 31556 + '</label>'; 31557 colTemplate.addEventListener('click', (e) => { 31558 modalColumnsPending.forEach(i => i.isSelected = i.Key === col.Key); 31559 CreateColumnPanel(modalColumnsPending, sortedColumnPending, $(e.target).closest('.sortable-table-modal').get(0), modalColumnFilters); 31560 }); 31561 CreateTooltip(colTemplate, col, modalPanel); 31562 menuItem.append(colTemplate); 31563 31564 if (col.AdvancedFiltersEnabled) { 31565 if (col.ValueType.toUpperCase() === BOOL_STRING.toUpperCase() || col.ValueType.toUpperCase() === NULLABLE_BOOL_STRING.toUpperCase()) { 31566 //add dropdown menu for boolean 31567 var boolDropdown = document.createElement('select'); 31568 boolDropdown.name = "booleanSelect"; 31569 boolDropdown.id = `${col.Key}_boolean_select`; 31570 boolDropdown.key = `${col.Key}`; 31571 boolDropdown.disabled = !col.IsVisible; 31572 boolDropdown.style.flex = '2.15'; 31573 boolDropdown.add(new Option(' ', '')); 31574 boolDropdown.add(new Option('Yes', `${TRUE_STRING}`)); 31575 boolDropdown.add(new Option('No', `${FALSE_STRING}`)); 31576 if (col.ValueType === "NullableBool") 31577 boolDropdown.add(new Option('Not set', `${NULL_STRING}`)); 31578 boolDropdown.value = `${modalColumnFilters.find(e => e.Key === col.Key).filterType}`; 31579 boolDropdown.addEventListener('change', (e) => {
31580 modalColumnFilters.forEach(i => { 31581 i.filterType = (i.Key === col.Key ? boolDropdown.value : i.filterType); 31582 i.text = (i.Key === col.Key ? boolDropdown.value : i.text); 31583 }); 31584 }); 31585 menuItem.append(boolDropdown); 31586 } 31587 else { 31588 //add dropdown menu 31589 var filterTypeDropdown = document.createElement('select'); 31590 filterTypeDropdown.name = "filtertype"; 31591 filterTypeDropdown.id = `${col.Key}_filter_type`; 31592 filterTypeDropdown.key = `${col.Key}`; 31593 filterTypeDropdown.disabled = !col.IsVisible; 31594 filterTypeDropdown.add(new Option('Contains', `${CONTAINS_STRING}`)); 31595 filterTypeDropdown.add(new Option('Equals', `${EQUALS_STRING}`)); 31596 filterTypeDropdown.add(new Option('Does not equal', `${NOT_EQUALS_STRING}`)); 31597 if (col.ValueType === "Number" || col.ValueType === "NumberString") { 31598 filterTypeDropdown.add(new Option('Greater than', `${GREATER_THAN_STRING}`)); 31599 filterTypeDropdown.add(new Option('Less Than', `${LESSER_THAN_STRING}`)); 31600 } 31601 filterTypeDropdown.value = `${modalColumnFilters.find(e => e.Key === col.Key).filterType}`; 31602 filterTypeDropdown.addEventListener('change', (e) => { 31603 modalColumnFilters.forEach(i => i.filterType = (i.Key === col.Key ? filterTypeDropdown.value : i.filterType)); 31604 }); 31605 menuItem.append(filterTypeDropdown); 31606 31607 //add text box 31608 var filterInput = document.createElement('input'); 31609 filterInput.type = 'text'; 31610 filterInput.id = `${col.Key}_col_filter`; 31611 filterInput.key = `${col.Key}`; 31612 filterInput.disabled = !col.IsVisible; 31613 filterInput.placeholder = 'Enter Value'; 31614 filterInput.value = modalColumnFilters.find(e => e.Key === col.Key).text; 31615 filterInput.addEventListener("keydown", function (event) { 31616 if (event.keyCode === 13) { 31617 event.preventDefault(); 31618 } 31619 }); 31620 filterInput.onkeyup = ((e) => { 31621 searchTimeout = setTimeout(() => { 31622 modalColumnFilters.forEach(i => i.text = (i.Key === col.Key ? filterInput.value : i.text)); 31623 }, 400); 31624 }) 31625 menuItem.append(filterInput); 31626 } 31627 } 31628 31629 selectMenu.append(menuItem); 31630 31631 if (col.isSelected) { 31632 moveUpButton = document.createElement('button'); 31633 moveUpButton.type = 'button'; 31634 moveUpButton.className = 'ForwardButtonShort'; 31635 moveUpButton.innerHTML = '<i class="fa fa-chevron-up"></i>'; 31636 moveUpButton.addEventListener('click', (e) => { 31637 const selectedIndex = modalColumnsPending.findIndex(i => i.isSelected); 31638 if (modalColumnsPending[selectedIndex - 1].IsDraggable && selectedIndex > 0) { 31639 const removed = modalColumnsPending.splice(selectedIndex, 1); 31640 modalColumnsPending.splice(selectedIndex - 1, 0, removed[0]); 31641 modalColumnsPending.forEach((col, index) => col.Order = index); 31642 CreateColumnPanel(modalColumnsPending, sortedColumnPending, $(e.target).closest('.sortable-table-modal').get(0), modalColumnFilters); 31643 } 31644 }); 31645 menuItem.append(moveUpButton); 31646 31647 moveDownButton = document.createElement('button');
31648 moveDownButton.type = 'button'; 31649 moveDownButton.className = 'ForwardButtonShort'; 31650 moveDownButton.innerHTML = '<i class="fa fa-chevron-down"></i>'; 31651 moveDownButton.addEventListener('click', (e) => { 31652 const selectedIndex = modalColumnsPending.findIndex(i => i.isSelected); 31653 if (selectedIndex < modalColumnsPending.length - 1) { 31654 if (modalColumnsPending[selectedIndex + 1].IsDraggable) { 31655 const removed = modalColumnsPending.splice(selectedIndex, 1); 31656 modalColumnsPending.splice(selectedIndex + 1, 0, removed[0]); 31657 modalColumnsPending.forEach((col, index) => col.Order = index); 31658 CreateColumnPanel(modalColumnsPending, sortedColumnPending, $(e.target).closest('.sortable-table-modal').get(0), modalColumnFilters); 31659 } 31660 } 31661 }); 31662 menuItem.append(moveDownButton); 31663 } 31664 } 31665 }); 31666 $(modalPanel).append(selectMenu); 31667 31668 const buttonUl = document.createElement('ul'); 31669 buttonUl.className = 'input-rows'; 31670 31671 const buttonLi = document.createElement('li'); 31672 buttonLi.className = 'action-row'; 31673 31674 buttonUl.appendChild(buttonLi); 31675 modalPanel.appendChild(buttonUl); 31676 31677 const resetDefaultButton = document.createElement('button'); 31678 resetDefaultButton.type = 'button'; 31679 resetDefaultButton.className = 'BackButton'; 31680 resetDefaultButton.innerHTML = 'Default View'; 31681 resetDefaultButton.addEventListener('click', (e) => { 31682 CreateColumnPanel(structuredClone(columnsOrig), null, $(e.target).closest('.sortable-table-modal').get(0), modalColumnFilters); 31683 }); 31684 buttonLi.appendChild(resetDefaultButton); 31685 31686 const clearConditionsButton = document.createElement('button'); 31687 clearConditionsButton.type = 'button'; 31688 clearConditionsButton.className = 'BackButton'; 31689 clearConditionsButton.innerHTML = 'Clear Conditions'; 31690 clearConditionsButton.addEventListener('click', (e) => { 31691 columnFilters = columnFiltersOrig; 31692 CreateColumnPanel(modalColumnsPending, null, $(e.target).closest('.sortable-table-modal').get(0), columnFilters); 31693 }); 31694 buttonLi.appendChild(clearConditionsButton); 31695 31696 const submitButton = document.createElement('button'); 31697 submitButton.type = 'button'; 31698 submitButton.className = 'ForwardButton'; 31699 submitButton.innerHTML = 'Save'; 31700 submitButton.onclick = function () { 31701 currentPage = 1; 31702 columns = modalColumnsPending; 31703 columnFilters = modalColumnFilters; 31704 sortedColumn = sortedColumnPending; 31705 $.fn.modalElement.close({ target: `#${wrapper.id} .sortable-table-modal` }); 31706 SaveTableSettings(); 31707 SortTable(sortedColumn, columnDescending); 31708 dataSource.forEach(item => item.IsVisible = true); 31709 FilterTableColumns(); 31710 DrawTable(); 31711 }; 31712 buttonLi.appendChild(submitButton); 31713 } 31714 31715 function AssignCheckboxFunctionality() { 31716 $(tbody).on('mousedown', function (e) { 31717 if (e.shiftKey) { 31718 e.preventDefault(); 31719 } 31720 }); 31721 31722 const setCheckboxState = (checkbox, checked) => { 31723 checkbox.checked = checked; 31724 if (checkbox.getAttribute('value')) { 31725 checkboxStatus[checkbox.value] = checked; 31726 $(checkbox).closest('tr').toggleClass('selected', checked); 31727 } 31728 }; 31729 31730 var checkboxList = [...tbody.querySelectorAll('input[type=checkbox]')]; 31731 checkboxList.forEach((c, index) => { 31732 c.id = `${wrapper.id}_${index}`; 31733 const cbLabel = document.createElement('label'); 31734 cbLabel.htmlFor = c.id; 31735 c.parentElement.insertBefore(cbLabel, c.parentElement.querySelector('input').nextSibling); 31736 c.parentElement.classList.add('checkbox'); 31737 31738 if (c.getAttribute('value')) { 31739 c.name = `${wrapper.id}_${index}`; 31740 31741 $(c).on('click', function (e) { 31742 setCheckboxState(c, c.checked); 31743 31744 const parentCB = $(`#${wrapper.id}_all`).get(0); 31745 31746 if (parentCB && parentCB.checked && !c.checked) { 31747 parentCB.checked = false; 31748 } 31749 31750 if (e.shiftKey && wrapper._lastCheckboxIndex != null) { 31751 const start = Math.min(wrapper._lastCheckboxIndex, index); 31752 const end = Math.max(wrapper._lastCheckboxIndex, index); 31753 31754 for (let subIndex = start; subIndex <= end; subIndex++) { 31755 setCheckboxState(checkboxList[subIndex], c.checked); 31756 } 31757 31758 if (parentCB && !c.checked) { 31759 parentCB.checked = false; 31760 } 31761 } 31762 31763 wrapper._lastCheckboxIndex = index; 31764 31765 UpdateCheckButtons(); 31766 }); 31767 } 31768 }); 31769 31770 var columnCheckboxes = [...thead.querySelectorAll('input[type=checkbox][data-toggle-column]')];
31771 columnCheckboxes.forEach(c => { 31772 c.id = `${wrapper.id}_all`; 31773 c.name = `${wrapper.id}_all`; 31774 c.checked = $(`input[type=checkbox][id^=${wrapper.id}_]`).toArray().every(i => i.checked || i.id === c.id); 31775 const cbLabel = document.createElement('label'); 31776 cbLabel.htmlFor = c.id; 31777 c.parentElement.insertBefore(cbLabel, c.parentElement.querySelector('input').nextSibling); 31778 c.parentElement.classList.add('checkbox'); 31779 c.addEventListener('change', () => CheckAllCheckboxes(c)); 31780 }); 31781 31782 } 31783 31784 function AssignRadioFunctionality() { 31785 var radioList = [...tbody.querySelectorAll('input[type=radio]')]; 31786 radioList.forEach((r, index) => { 31787 // if we don't add "radio", the ids will overlap with checkbox ids from AssignCheckboxFunctionality, this causes causes the checkboxes 31788 // to be selected instead of the correct radio button when you click it. This would be a headache. 31789 r.id = `${wrapper.id}_radio_${index}`; 31790 const rbLabel = document.createElement('label'); 31791 rbLabel.htmlFor = r.id; 31792 r.parentElement.insertBefore(rbLabel, r.parentElement.querySelector('input').nextSibling); 31793 r.parentElement.classList.add('checkbox'); 31794 31795 if (r.getAttribute('value')) { 31796 const classList = (r.getAttribute('class') || '').toLowerCase().split(' '); 31797 if (classList.includes('value') || classList.includes('id')) 31798 r.name = `${wrapper.id}_`; 31799 else 31800 r.name = r.name ?? `${wrapper.id}_`; 31801 } 31802 }); 31803 } 31804 31805 31806 function UpdateCheckButtons() { 31807 let buttonsEnabled = Object.values(checkboxStatus).some(v => v === true); 31808 if (!buttonsEnabled) { 31809 let checkboxList = [...tbody.querySelectorAll('input[type=checkbox]')]; 31810 checkboxList.forEach((c, index) => { 31811 if (c.checked === true) { 31812 buttonsEnabled = true; 31813 } 31814 }); 31815 } 31816 enabledWhenCheckedButtons.forEach(b => { 31817 b.disabled = !buttonsEnabled; 31818 }); 31819 updateTitle(); 31820 } 31821 31822 function CheckAllCheckboxes(source) { 31823 const columnKey = source.closest('th').getAttribute('data-columnKey'); 31824 const checkboxes = [...tbody.querySelectorAll(`input[type=checkbox].${columnKey},input[type=checkbox][key=${columnKey}]`)]; 31825 checkboxes.forEach(c => { 31826 const changed = c.checked !== source.checked 31827 c.checked = source.checked; 31828 if (changed) { 31829 $(c).trigger('change'); 31830 } 31831 $(c).closest('tr').toggleClass('selected', source.checked); 31832 checkboxStatus[c.value] = c.checked; 31833 }); 31834 const selectedRecords = [...tbody.querySelectorAll('input[type=checkbox][value]:is(:checked)')].length; 31835 const buttonsEnabled = selectedRecords > 0; 31836 enabledWhenCheckedButtons.forEach(b => { 31837 b.disabled = !buttonsEnabled; 31838 }); 31839 updateTitle(); 31840 } 31841 31842 function AssignEnterKeyFunctionality() { 31843 // Enter goes down, Shift+Enter goes up 31844 31845 $(tbody).on('keypress', 'input, select', function (e) { 31846 if (e.keyCode === 13) { 31847 e.preventDefault(); 31848 e.stopPropagation(); 31849 31850 const goUp = e.shiftKey; 31851 const $td = $(this).closest('td'); 31852 const $tr = $(this).closest('tr'); 31853 const tdCount = $tr.find('td').length; 31854 let colIndex = $(this).closest('tr').find('td').index($td); 31855 let rowIndex = $(this).closest('tbody').find('tr').index($tr); 31856 const $trs = $(tbody).find('tr'); 31857 31858 rowIndex = goUp ? rowIndex - 1 : rowIndex + 1; 31859 31860 if (rowIndex === $trs.length) { 31861 colIndex += 1;
31862 } 31863 else if (rowIndex === -1) { 31864 colIndex -= 1; 31865 } 31866 31867 if (colIndex === tdCount) { 31868 colIndex = 0; 31869 } 31870 else if (colIndex === -1) { 31871 colIndex = tdCount - 1; 31872 } 31873 31874 const $nextCell = $trs.eq(rowIndex).find('td').eq(colIndex); 31875 $nextCell.find('input:visible, select:visible').trigger('focus'); 31876 } 31877 }); 31878 } 31879 31880 31881 function LockColumns() { 31882 let lockedColumnCount = 0; 31883 31884 for (lockedColumnCount; 31885 table.querySelectorAll(`.lock${lockedColumnCount + 1}`).length > 0; 31886 lockedColumnCount++) { } 31887 31888 if (lockedColumnCount === 0) 31889 return; 31890 31891 let lastWidth = 0; 31892 31893 for (let i = 0; i <= lockedColumnCount; i++) { 31894 let thisWidth = 0; 31895 const lockedEntries = table.querySelectorAll(`.lock${i + 1}`); 31896 lockedEntries.forEach(item => { 31897 item.style.left = lastWidth + 'px'; 31898 thisWidth = item.offsetWidth; 31899 }) 31900 lastWidth += thisWidth; 31901 } 31902 } 31903 31904 function HasTimeZoneSuffix(text) { 31905 if (!text || typeof text !== 'string') return false; 31906 const s = text.trim(); 31907 const m = s.match(/\s([A-Z]{2,5})$/); // RegEx to look for the last 2â5 uppercase letters in the Date 31908 if (!m) return false; 31909 const tz = m[1]; 31910 return tz !== 'AM' && tz !== 'PM'; 31911 } 31912 31913 31914 function TableButtonPostBack(arg) { 31915 __doPostBack(`${wrapper.id}$TableRowEvent`, JSON.stringify(arg)); 31916 } 31917 31918 function OpenModalConfirm(confirmMessage, arg) { 31919 $.fn.modalConfirm.open({ 31920 content: confirmMessage || 'Are you sure?', 31921 confirm: () => TableButtonPostBack(arg) 31922 }); 31923 31924 const confirmInputs = document.querySelectorAll('.smp-modal.confirm [smp-table-confirm-input]'); 31925 const confirmInput = confirmInputs[confirmInputs.length - 1]; 31926 if (confirmInput) { 31927 const readConfirmInput = () => arg.input = confirmInput.type === 'checkbox' ? confirmInput.checked : confirmInput.value; 31928 readConfirmInput(); 31929 confirmInput.addEventListener('change', readConfirmInput); 31930 } 31931 } 31932 31933 function ExportExcelPostBack() { 31934 __doPostBack(`${wrapper.id}$CustomExportToExcel`, ''); 31935 } 31936 31937 function GetExportDataValues({ parentRowsVisible, childRowsVisible } = { parentRowsVisible: true, childRowsVisible: true }) { 31938 let rows = []; 31939 const visibleColumns = columns 31940 .filter(c => c.IsVisible && c.ExportEnabled); 31941 31942 dataSource 31943 .filter(i => i.IsVisible !== false) 31944 .forEach(dataRow => { 31945 if (parentRowsVisible) { 31946 const standardItem = []; 31947 visibleColumns 31948 .forEach(column => { 31949 let col = dataRow.Data.find(e => e[keyName] === column.Key); 31950 let item; 31951 if (col) { 31952 31953 var __fmt = (typeof (col[formatName]) === 'string') ? GetInnerTextOfHtml(col[formatName]) : ''; 31954 if (__fmt && HasTimeZoneSuffix(__fmt)) { 31955 item = __fmt; 31956 } 31957 31958 if (col[valueName] && !item) { 31959 item = GetInnerTextOfHtml(col[valueName]); 31960 } 31961 31962 if (typeof (col[formatName]) === 'string' && !item) { 31963 item = __fmt || GetInnerTextOfHtml(col[formatName]); 31964 } 31965 31966 standardItem.push(item); 31967 } 31968 else { 31969 standardItem.push(''); 31970 } 31971 }); 31972 31973 rows.push(standardItem); 31974 } 31975 31976 if (childRowsVisible) { 31977 if (dataRow.IsChildrenVisible) {
31978 dataRow.ChildItems.forEach(subRow => { 31979 const detailItem = []; 31980 31981 visibleColumns 31982 .forEach(subColumn => { 31983 let detailCol = subRow.find(r => r[keyName] === subColumn.Key); 31984 let detailItemValue = ''; 31985 31986 if (detailCol) { 31987 var __fmtChild = (typeof (detailCol[formatName]) === 'string') ? GetInnerTextOfHtml(detailCol[formatName]) : ''; 31988 if (__fmtChild && HasTimeZoneSuffix(__fmtChild)) { 31989 detailItemValue = __fmtChild; 31990 } 31991 31992 if (detailCol[valueName] && !detailItemValue) { 31993 detailItemValue = GetInnerTextOfHtml(detailCol[valueName]); 31994 } 31995 31996 if (typeof (detailCol[formatName]) === 'string' && !detailItemValue) { 31997 detailItemValue = __fmtChild || GetInnerTextOfHtml(detailCol[formatName]); 31998 } 31999 } 32000 32001 detailItem.push(detailItemValue); 32002 }); 32003 32004 rows.push(detailItem); 32005 }); 32006 } 32007 } 32008 }); 32009 32010 return rows; 32011 } 32012 32013 function GetExportFooterValues() { 32014 let row = []; 32015 32016 if (_instanceSettings.FooterVisible) { 32017 const visibleColumns = columns 32018 .filter(c => c.IsVisible && c.ExportEnabled); 32019 32020 row = visibleColumns 32021 .map(column => { 32022 const footer = footers.find(f => f[keyName] === column.Key); 32023 return footer !== undefined ? (displayFormat(footer)) : ""; 32024 }); 32025 } 32026 32027 return row; 32028 } 32029 32030 function GetColumnsToExport() { 32031 return columns 32032 .filter(c => c.IsVisible && c.ExportEnabled) 32033 .map(c => GetInnerTextOfHtml(c.Label)); 32034 } 32035 32036 function GetColumnValueTypesToExport() { 32037 return columns 32038 .filter(c => c.IsVisible && c.ExportEnabled) 32039 .map(c => c.ValueType); 32040 } 32041 32042 function AddExpandedChildRowsSheet(sheets, columns, valueTypes) { 32043 const dataVals = GetExportDataValues({ childRowsVisible: true, parentRowsVisible: false }); 32044 32045 if (dataVals.length === 0) 32046 return; 32047 32048 sheets.push({ 32049 columns, valueTypes, title: 'Expanded Rows', footerVisible: false, data: dataVals, 32050 headerRows: [{ topOfSheet: true, cells: ['These are the rows you expanded without any header rows'], spacerRowsAfter: 1 }] 32051 }); 32052 } 32053 32054 function ExportDataToExcel({ startNewSheet } = { startNewSheet: false }) { 32055 32056 const sheets = []; 32057 32058 const dataVals = GetExportDataValues(); 32059 if (dataVals.length === 0) return; 32060 const columns = GetColumnsToExport(); 32061 const valueTypes = GetColumnValueTypesToExport(); 32062 32063 const footerVisible = startNewSheet === false && _instanceSettings.FooterVisible; 32064 let currentSheet = null; 32065 32066 for(let rowIndex = 0; rowIndex < dataVals.length; rowIndex++) 32067 { 32068 const newSheet = startNewSheet !== false && startNewSheet(dataVals, rowIndex); 32069 if(newSheet || currentSheet === null) 32070 { 32071 currentSheet = { columns, valueTypes, footerVisible, data: [], ...newSheet }; 32072 sheets.push(currentSheet); 32073 } 32074 32075 currentSheet.data.push(dataVals[rowIndex]); 32076 } 32077 32078 if (startNewSheet === false && _instanceSettings.FooterVisible) { 32079 currentSheet.data.push(GetExportFooterValues()); 32080 } 32081 32082 AddExpandedChildRowsSheet(sheets, columns, valueTypes); 32083 32084 const excelInput = { 32085 title: _title, 32086 affiliationId: affiliationId, 32087 sheets 32088 }; 32089 32090 if (dataVals.length > 500) { 32091 $.fn.modalAlert.open({ content: `Download of ${dataVals.length.toLocaleStr
32091ing()} rows will start in a moment` }); 32092 } 32093 32094 const excelPostBack = () => { 32095 fetch(`/api/file/excel`, 32096 { 32097 method: 'POST', 32098 headers: { 32099 'Content-Type': 'application/json' 32100 }, 32101 body: JSON.stringify(excelInput) 32102 }) 32103 .then((res) => { 32104 if (!res.ok) { 32105 return Promise.reject(res); 32106 } 32107 32108 let contentDisposition = res.headers.get('content-disposition'); 32109 let title = (contentDisposition || '').split('filename=\"')[1]; 32110 if (title) 32111 title = title.replace('"', ''); 32112 32113 res.blob() 32114 .then(blob => { 32115 const fileUrl = URL.createObjectURL(blob); 32116 const fileLink = document.createElement('a'); 32117 fileLink.href = fileUrl; 32118 fileLink.download = title; 32119 fileLink.click(); 32120 }); 32121 }); 32122 }; 32123 32124 excelPostBack(); 32125 } 32126 32127 function CustomMenuButtonPostBack(data) { 32128 __doPostBack(`${wrapper.id}$CustomButtonEvent`, JSON.stringify(data)); 32129 } 32130 32131 function FilterTableColumns() { 32132 const visibleColumns = columns 32133 .filter(column => column.IsVisible); 32134 32135 dataSource.forEach(item => { 32136 let tempIsVisible = true; 32137 visibleColumns.forEach(column => { 32138 if (column.IsVisible !== false) { 32139 const colFilter = columnFilters.find(f => f.Key === column.Key); 32140 const filterInputText = colFilter.text.toUpperCase(); 32141 var colMakesVisible = true; 32142 if (filterInputText.length > 0) { 32143 colMakesVisible = false; 32144 const filterType = colFilter.filterType.toUpperCase(); 32145 const filterInputSplit = filterInputText.split(' ').map(e => e.toUpperCase().trimEnd()); 32146 const searchableTerms = []; 32147 32148 const col = item.Data.find(d => d[keyName] === column.Key); 32149 32150 if (col) { 32151 if (!!col[valueName]) { 32152 const val = item.Data.find(d => d[keyName] === column.Key)[valueName]; 32153 searchableTerms.push(val.toString()); 32154 } 32155 if (!!col[formatName]) { 32156 const formatted = item.Data.find(d => d[keyName] === column.Key)[formatName]; 32157 searchableTerms.push(GetInnerTextOfHtml(formatted)); 32158 } 32159 } 32160 32161 if (item.ChildItems !== undefined) { 32162 item.ChildItems.forEach(child => { 32163 const childcol = child.find(d => d[keyName] === column.Key); 32164 32165 if (childcol && !!childcol[formatName]) { 32166 const formatted = child.find(d => d[keyName] === column.Key)[formatName]; 32167 const innerText = GetInnerTextOfHtml(formatted); 32168 32169 if(!searchableTerms.includes(innerText)){ 32170 searchableTerms.push(innerText); 32171 } 32172 } 32173 else if (childcol && !!childcol[valueName]) { 32174 const val = child.find(d => d[keyName] === column.Key)[valueName]; 32175 if (val === false || val === true) 32176 return null; 32177 searchableTerms.push(val.toString()); 32178 } 32179 }); 32180 } 32181 32182 if (filterType == CONTAINS_STRING.toUpperCase()) { 32183 if (TermIsFound(searchableTerms, filterInputSplit)) { 32184 colMakesVisible = true; 32185 } 32186 } 32187 else if (filterType == EQUALS_STRING.toUpperCase()) { 32188 if (TermEquals(searchableTerms, filterInputText)) 32189 colMakesVisible = true; 32190 } 32191 else if (filterType == NOT_EQUALS_STRING.toUpperCase()) { 32192 if (TermNotEquals(searchableTerms, filterInputText)) 32193 colMakesVisible = true; 32194 } 32195 else if (filterType == GREATER_THAN_STRING.toUpperCase()) { 32196 const val = item.Data.find(d => d[keyName] === column.Key)[valueName]; 32197 if (TermCompare(val, filterInputText, true)) 32198 colMakesVisible = true; 32199 } 32200 else if (filterType == LESSER_THAN_STRING.toUpperCase()) { 32201 const val = item.Data.find(d => d[keyName] === column.Key)[valueName]; 32202 if (TermCompare(val, filterInputText, false)) 32203 colMakesVisible = true; 32204 } 32205 else { 32206 const searchableBools = []; 32207 if (col) { 32208 val = col[valueName]; 32209 if (val === true || val === false || val === null) { 32210 searchableBools.push(val === null ? NULL_STRING : val === false ? FALSE_STRING : TRUE_STRING); 32211 } 32212 if (column.ForceFilterType?.toUpperCase() === BOOL_STRING.toUpperCase()) { 32213 searchableBools.push(val !== null ? TRUE_STRING : FALSE_STRING); 32214 } 32215 else if (column.ValueType === BOOL_STRING.toUpperCase()) { 32216 32217 searchableBools.push(val !== null ? TRUE_STRING : FALSE_STRING); 32218 } 32219 } 32220 if (item.ChildItems !== undefined) {
32221 item.ChildItems.forEach(child => { 32222 const childcol = child.find(d => d[keyName] === column.Key); 32223 let val = childcol[valueName]; 32224 if (childcol) { 32225 if (val === true || val === false || val === null){ 32226 searchableBools.push(val === null ? NULL_STRING : val === false ? FALSE_STRING : TRUE_STRING); 32227 } 32228 else if (column.ValueType === BOOL_STRING.toUpperCase()) { 32229 searchableBools.push(val !== null ? TRUE_STRING : FALSE_STRING); 32230 } 32231 } 32232 }); 32233 } 32234 32235 if (filterType === TRUE_STRING.toUpperCase()) { 32236 if (BoolTerm(searchableBools, TRUE_STRING)) 32237 colMakesVisible = true; 32238 } 32239 else if (filterType === FALSE_STRING.toUpperCase()) { 32240 if (BoolTerm(searchableBools, FALSE_STRING)) 32241 colMakesVisible = true; 32242 } 32243 else if (filterType === NULL_STRING.toUpperCase()) { 32244 if (BoolTerm(searchableBools, NULL_STRING)) 32245 colMakesVisible = true; 32246 } 32247 } 32248 } 32249 if (tempIsVisible) {
32250 tempIsVisible = colMakesVisible; 32251 } 32252 } 32253 }); 32254 showFooter = (!tempIsVisible ? false : showFooter); 32255 item.IsVisible = (item.IsVisible !== false ? tempIsVisible : item.IsVisible); 32256 }); 32257 shownResultsLength = dataSource.filter(i => i.IsVisible !== false).length; 32258 evaluateCustomizeBtnClass(); 32259 32260 updateTitle(); 32261 } 32262 32263 function SaveTableSettings() { 32264 if (!tableIdentifier) { 32265 console.warn('missing tableIdentifier'); 32266 return; 32267 } 32268 32269 const columnSettings = columns.map(c => ({ 32270 Key: c.Key, 32271 IsVisible: c.IsVisible, 32272 Order: c.Order 32273 })); 32274 const tableSettings = { 32275 affiliationId, 32276 tableIdentifier, 32277 settings: { 32278 sortedColumn, 32279 columnDescending, 32280 columns: columnSettings 32281 } 32282 }; 32283 32284 evaluateCustomizeBtnClass(); 32285 tableSettingsPostBack(tableSettings); 32286 } 32287 32288 const tableSettingsPostBack = (tableSettings) => fetch(`/api/user/table-preferences`, 32289 { 32290 method: 'PUT', 32291 headers: { 32292 'Content-Type': 'application/json' 32293 }, 32294 body: JSON.stringify(tableSettings) 32295 }); 32296 32297 function CreateTooltip(parentElement, column, boundingBox) { 32298 if (column.Tooltip !== undefined) { 32299 const tooltipIcon = document.createElement('i') 32300 tooltipIcon.className = 'fas fa-question-circle'; 32301 tooltipIcon.title = column.Tooltip; 32302 tooltipIcon.style.marginLeft = '5px'; 32303 tooltipIcon.addEventListener('mouseover', (e) => ShowTooltip(e, boundingBox)); 32304 tooltipIcon.addEventListener('mouseout', (e) => HideTooltip(e)); 32305 parentElement.appendChild(tooltipIcon); 32306 } 32307 } 32308 32309 function ShowTooltip(event, boundingBox) { 32310 const tooltipPanel = document.createElement('span'); 32311 tooltipPanel.className = 'tooltip-panel'; 32312 tooltipPanel.innerHTML = event.target.title; 32313 32314 event.target.title = ""; 32315 event.target.parentElement.style.zIndex = "5"; 32316 event.target.appendChild(tooltipPanel); 32317 event.target._tooltipRef = tooltipPanel; 32318 32319 //transform tooltip 32320 const tooltipRect = tooltipPanel.getBoundingClientRect(); 32321 const tooltipRightX = tooltipRect.x + tooltipRect.width; 32322 const tooltipBottomY = tooltipRect.y + tooltipRect.height; 32323 const tableRect = boundingBox.getBoundingClientRect(); 32324 const tableRightX = tableRect.x + tableRect.width; 32325 const tableBottomY = tableRect.y + tableRect.height; 32326 //if (tooltipRect.x < 0) { 32327 // tooltipPanel.style.transform = `translateX(${-tooltipRect.x}px)`; 32328 //} else if (tooltipRightX > tableRightX) { 32329 // tooltipPanel.style.transform = `translateX(${(tableRightX - tooltipRightX)}px)`; 32330 //} 32331 const xTransform = (tooltipRect.x < 0 ? -tooltipRect.x : 32332 (tooltipRightX > tableRightX ? (tableRightX - tooltipRightX) : 32333 0)); 32334 const yTransform = (tooltipRect.y < 0 ? -tooltipRect.y : 32335 (tooltipBottomY > tableBottomY ? (tableBottomY - tooltipBottomY) : 32336 0)); 32337 tooltipPanel.style.transform = `translate(${xTransform}px,${yTransform}px)`; 32338 } 32339 32340 function HideTooltip(event) { 32341 event.target.parentElement.style.zIndex = (event.target.parentElement.classList.contains("is-locked") ? "2" : "1"); 32342 event.target.title = event.target._tooltipRef.innerHTML; 32343 event.target.removeChild(event.target._tooltipRef); 32344 } 32345 32346 function LoadDataAsync() { 32347 //display loading spinner 32348 showSpinner(wrapper); 32349 if (!_instanceSettings.DataEndpoint) { 32350 console.warn('No data endpoint defined for this table.'); 32351 hideSpinner(wrapper); 32352 return; 32353 } 32354 const sanitizedPathname = window.location.pathname.replace(/\/+$/, ''); 32355 const endpoint = `${sanitizedPathname}/${_instanceSettings.DataEndpoint}`; 32356 const requestBody = _instanceSettings.RequestBody || {}; 32357 fetch(endpoint, { 32358 method: 'POST', 32359 headers: { 32360 'Content-Type': 'application/json' 32361 }, 32362 body: JSON.stringify(requestBody) 32363 }) 32364 .then(response => response.json()) 32365 .then(data => { 32366 dataSource = data.d.Data; 32367 footers = data.d.Footer || footers; 32368 columns = data.d.Columns ? JSON.parse(data.d.Columns) : columns; 32369 sortCache = { column: null, ascending: null, sortedData: null }; 32370 dataSourceOrig = dataSource; 32371 refreshTableData(); 32372 hideSpinner(wrapper); 32373 if (_instanceSettings.PostLoadCallback) { 32374 try { 32375 eval(_instanceSettings.PostLoadCallback); 32376 } catch (error) { 32377 console.error('Error executing PostLoadCallback:', error); 32378 } 32379 } 32380 }) 32381 .catch(error => { 32382 console.error('Error fetching data:', error); 32383 hideSpinner(wrapper); 32384 }); 32385 } 32386 32387 function animateRotate($icon) { 32388 var duration = 1000; 32389 setTimeout(function () { 32390 animateRotate($icon); 32391 }, duration); 32392 32393 $({ deg: 0 }).animate({ deg: 360 }, { 32394 duration: duration, 32395 step: function (now) { 32396 $icon.css({ 32397 'transform': 'rotate(' + now + 'deg)' 32398 }); 32399 }, 32400 easing: 'linear' 32401 }); 32402 } 32403 32404 function showSpinner(table) { 32405 const spinner = table.querySelector('.sortable-loading-spinner'); 32406 if (spinner) { 32407 $(spinner).css('display', 'flex').show(); 32408 animateRotate($(".fa-spinner")); 32409 } 32410 } 32411 32412 function hideSpinner(table) { 32413 const spinner = table.querySelector('.sortable-loading-spinner'); 32414 if (spinner) { 32415 $(spinner).hide(); 32416 } 32417 } 32418 32419 function refreshTableData() { 32420 totalResultsLength = undefined; 32421 shownResultsLength = undefined; 32422 RefreshTable(wrapper, dataSource, columns, footers, _userPrefs, _instanceSettings, _title); 32423 } 32424 32425 function DestroyTable(wrapper) { 32426 wrapper.innerHTML = ''; 32427 } 32428 32429 function RefreshTable(wrapper, newDataSource, newColumns, newFooter, newUserPrefs, newInstanceSettings, newTitle) { 32430 DestroyTable(wrapper); 32431 CreateTable(wrapper.id, newColumns, newDataSource, newFooter, newUserPrefs, newInstanceSettings, newTitle, true); 32432 } 32433 32434 32435 function draggableTableListenerCreator() { 32436 let isDown = false; 32437 let startX, startY, scrollLeft, scrollTop; 32438 32439 tbody.addEventListener('mousedown', (e) => { 32440 if (e.ctrlKey) { 32441 isDown = true; 32442 tbody.style.cursor = 'grabbing'; 32443 tbody.style.userSelect = 'none'; 32444 startX = e.pageX - table.offsetLeft; 32445 scrollLeft = table.scrollLeft; 32446 startY = e.pageY - table.offsetTop; 32447 scrollTop = table.scrollTop; 32448 } 32449 }) 32450 32451 tbody.addEventListener('mouseleave', (e) => { 32452 isDown = false; 32453 if (tbody.style.cursor.length > 0) { 32454 tbody.style.removeProperty('cursor') 32455 } 32456 }) 32457 32458 tbody.addEventListener('mouseup', (e) => { 32459 if (isDown) { 32460 isDown = false; 32461 tbody.style.removeProperty('cursor') 32462 tbody.style.removeProperty('user-select'); 32463 } 32464 }) 32465 32466 tbody.addEventListener('mousemove', (e) => { 32467 if (e.ctrlKey) { 32468 if (!isDown) return; 32469 e.preventDefault(); 32470 const x = e.pageX - table.offsetLeft; 32471 const walkLeft = (x - startX); 32472 table.scrollLeft = scrollLeft - walkLeft; 32473 32474 const y = e.pageY - table.offsetTop; 32475 const walkTop = (y - startY); 32476 table.scrollTop = scrollTop - walkTop; 32477 } 32478 }) 32479 } 32480 32481 function paginate(array) { 32482 let startIndex = 0; 32483 let endIndex = totalResultsLength; 32484 32485 if (_instanceSettings.MaxRenderedRows) { 32486 endIndex = _instanceSettings.MaxRenderedRows; 32487 } 32488 32489 if (_instanceSettings.PaginationVisible) { 32490 startIndex = (currentPage - 1) * pageSize; 32491 endIndex = startIndex + pageSize; 32492 } 32493 32494 return array.filter(r => r.IsVisible).slice(startIndex, endIndex); 32495 } 32496 32497 function isInViewport(element) { 32498 const rect = element.getBoundingClientRect(); 32499 return ( 32500 rect.top >= 0 && 32501 rect.left >= 0 && 32502 rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && 32503 rect.right <= (window.innerWidth || document.documentElement.clientWidth) 32504 ); 32505 } 32506 32507 function loadAsyncWhenVisible() { 32508 $(window).on('scroll resize', function() { 32509 if (isInViewport(wrapper)) { 32510 LoadDataAsync(); 32511 $(window).off('scroll resize'); 32512 } 32513 }); 32514 32515 if (isInViewport(wrapper)) { 32516 LoadDataAsync(); 32517 $(window).off('scroll resize'); 32518 } 32519 } 32520 32521 return { 32522 CreateTable 32523 }; 32524};
32525 32526(function () { 32527 function popupContainerHasTarget(popup, target) { 32528 return popup.parentElement !== null && popup.parentElement.contains(target); 32529 } 32530 32531 $(document).on('click.tableDropdownModal', function (e) { 32532 const clickedDetachedNode = !document.contains(e.target); 32533 const clickedDatePicker = $(e.target).closest('.ui-datepicker').length > 0; 32534 if (clickedDetachedNode || clickedDatePicker) { 32535 return; 32536 } 32537 32538 $('.table-dropdown-modal:visible').each(function () { 32539 if (!popupContainerHasTarget(this, e.target)) { 32540 $(this).hide(); 32541 } 32542 }); 32543 32544 requestAnimationFrame(() => { 32545 $('.table-dropdown-modal:visible').each(function () { 32546 if (popupContainerHasTarget(this, e.target)) { 32547 this.scrollIntoView({ block: 'nearest', inline: 'nearest', behavior: 'smooth' }); 32548 } 32549 }); 32550 }); 32551 }); 32552})(); 32553 32554 32555; 32556////pf: javascript/file-manager.js 32557let currentPath = ""; 32558let searchTimeout = null; 32559let showImages = false; 32560let showDocs = false; 32561let showVideos = false; 32562let affiliationNames = []; 32563let isAdmin = false; 32564let collegeLogosPath = ''; 32565let canEditCollegeLogos = false; 32566 32567 32568$(function () { 32569 if ($('#FileManager').length === 0) { 32570 return; 32571 } 32572 32573 $('.horizontal-menu a').on('click', function () { 32574 $('.horizontal-menu li').removeClass('selected'); 32575 $(this).closest('li').addClass('selected'); 32576 }); 32577 32578 32579 $(window).on('hashchange', function () { 32580 const hash = window.location.hash.substring(1); 32581 if (currentPath !== hash) { 32582 LoadFiles(hash); 32583 } 32584 }); 32585 32586 $('#FileManager .SearchText').keyup(function () { 32587 clearTimeout(searchTimeout); 32588 searchTimeout = setTimeout(() => LoadFiles(window.location.hash.substring(1)), 300); 32589 }); 32590 32591 function toggleUploadView() { 32592 $('#FileUploadView').toggle(); 32593 $('#ListView').toggle(); 32594 $('#global-file-upload-li').toggleClass( 'disabled', !IsGlobalContentAdmin && !IsGlobalTabSelected() && $('#FileUploadView').css('display') !== 'none'); 32595 } 32596 32597 function IsGlobalTabSelected() { 32598 return $('#global-file-upload-li').hasClass('selected'); 32599 } 32600 32601 $('[toggle-file-upload-view]').on('click', toggleUploadView); 32602 32603 $('#inputFolder').on('input', function () { 32604 const name = $("#inputFolder").val() || ''; 32605 const error = getFolderNameValidationError(name); 32606 updateFolderNameValidation(error); 32607 }); 32608 32609 $('#save-folder-button').on('click', () => { 32610 const rawName = $("#inputFolder").val() || ''; 32611 const error = getFolderNameValidationError(rawName); 32612 if (error) { 32613 updateFolderNameValidation(error); 32614 return; 32615 } 32616 32617 const name = rawName.trim(); 32618 $('#Processing').toggle(true); 32619 32620 fetch(`/api/file/directory${currentPath}/${encodeURIComponent(name)}`, 32621 { 32622 method: "POST", 32623 headers: { 'Content-Type': 'application/json' } 32624 }) 32625 .then((res) => { 32626 $('#Processing').toggle(false); 32627 if (!res.ok) { 32628 return res.text().then((text) => { 32629 let message = 'Failed to save'; 32630 try { 32631 const parsed = JSON.parse(text); 32632 message = parsed.Message || parsed.message || message; 32633 } catch (e) { 32634 if (text) { 32635 message = text; 32636 } 32637 } 32638 $.fn.modalAlert.open({ content: message }); 32639 }); 32640 } 32641 32642 LoadFiles(currentPath); 32643 $('#new-folder-modal').toggle(false); 32644 resetFolderNameForm(); 32645 }) 32646 .catch(() => { 32647 $('#Processing').toggle(false); 32648 $.fn.modalAlert.open({ content: 'Failed to save' }); 32649 }); 32650 }); 32651 32652 $('#DirectoryList').on("click", "[path]", 32653 function () { 32654 const path = $(this).attr('path'); 32655 LoadFiles(path);
32656 }); 32657 32658 $('#FileList').on("dblclick", "[path]", 32659 function () { 32660 const path = $(this).attr('path'); 32661 $.fn.modalFrame.open({ src: `https://smpfiles.blob.core.windows.net/uploads/${path}` }); 32662 }); 32663 32664 $('[insert-file]').on('click', () => { 32665 let path = $("#FileList li.selected").attr('path'); 32666 if (path) { 32667 if (width && height) { 32668 let img = $("#FileList li.selected").find("img").get(0); 32669 const imageWidth = parseFloat(img.naturalWidth); 32670 const imageHeight = parseFloat(img.naturalHeight); 32671 if (imageHeight !== 0 && height !== 0 && Math.abs(imageWidth / imageHeight - parseFloat(width) / height) > 0.05) { //leeway of 0.05 dimension ratio so resizing to a size that doesn't perfectly match still works 32672 const $content = 32673 $(`<div> 32674 <h2>Image Not Uploaded</h2> 32675 <p>Ad Image file must match the following size requirement: ${width} x ${height} pixels.</p> 32676 </div>`); 32677 32678 $.fn.modalElement.open({ content: $content }); 32679 return; 32680 } 32681 } 32682 32683 const isGif = path.toLowerCase().endsWith('.gif'); 32684 // If inserting an image when composing an email then we need to resize it instead of serving it from blob storage 32685 if (showImages && imageResize && !isGif) { 32686 path = `https://resized-images.azureedge.net/uploads/${path}?${imageResize}`; 32687 } else { 32688 path = `https://smpfiles.blob.core.windows.net/uploads/${path}`; 32689 } 32690 32691 window.InsertFile(path); 32692 } 32693 }); 32694 32695 $('[delete-file]').on('click', () => { 32696 DeleteFile(); 32697 }); 32698 32699 $('[start-upload]').on('click', () => { 32700 const files = $('.fileinput-button input').get(0).files; 32701 const affiliationId = currentPath.replace('/uploads/', '').split('/')[0]; 32702 var split = currentPath.split('/').slice(2); 32703 const affiliationPath = split.filter(i => i !== '').join('/'); 32704 32705 var idArray = split.reduce(function (arr, item, index) { 32706 if (item === "Team") arr.push(index); 32707 return arr; 32708 }, []); 32709 32710 var teamId = idArray.length > 0 ? split[idArray[0] + 1] : null; 32711 const fileRegex = /[&\/\\#,+()$~%'":*?<>{}]/g; 32712 32713 const uploadTasks = Array.from(files).map( 32714 async file => { 32715 var fileToSend = file; 32716 if (fileRegex.test(file.name)) { 32717 var newFile = new File([file], file.name.replace(fileRegex, '_'), { type: file.type }); 32718 fileToSend = newFile; 32719 } 32720 32721 await fetch( 32722 `/api/file?container=uploads&affiliationid=${(affiliationId !== 'global' ? affiliationId : '')}&name=${affiliationPath}/${fileToSend.name}&overwrite=${isAdmin}&teamid=${teamId}`, 32723 { 32724 method: 'POST', 32725 body: fileToSend, 32726 headers: { 32727 'Content-Type': 'application/json' 32728 } 32729 }) 32730 } 32731 ); 32732 32733 Promise.all(uploadTasks) 32734 .then((res) => { 32735 toggleUploadView(); 32736 LoadFiles(currentPath); 32737 }) 32738 .catch((res) => $.fn.modalAlert.open({ content: 'An error occurred' })); 32739 }); 32740 32741 $('[create-folder]').on('click', () => { 32742 resetFolderNameForm(); 32743 $.fn.modalElement.open({ target: '#new-folder-modal' }); 32744 }); 32745 32746 $('[delete-folder]').on('click', () => { 32747 DeleteFolder(); 32748 }); 32749 32750 showImages = window.location.search.match(/type=image/); 32751 showDocs = window.location.search.match(/type=doc/); 32752 showVideos = window.location.search.match(/type=video/); 32753 32754 $('#FileListHeader h2').html(showDocs ? "Documents" : showVideos ? "Videos" : showImages ? "Images" : "Files"); 32755 32756 LoadFiles(currentPath); 32757}); 32758 32759const folderNameInvalidCharPattern = /[&\/\\#,+()$~%'":*?<>{}]/g; 32760 32761function getFolderNameValidationError(name) { 32762 if (!name || !name.trim()) { 32763 return 'Folder name is required'; 32764 } 32765 32766 if (name !== name.trim()) { 32767 return 'Folder name cannot start or end with spaces'; 32768 } 32769 32770 if (name === '.' || name === '..') {
32771 return 'Folder name is invalid'; 32772 } 32773 32774 const invalidChars = name.match(folderNameInvalidCharPattern); 32775 if (invalidChars) { 32776 const uniqueChars = [...new Set(invalidChars)]; 32777 const listed = uniqueChars.map(c => `'${c}'`).join(', '); 32778 return `Folder name cannot contain ${listed}`; 32779 } 32780 32781 if (name.endsWith('.')) { 32782 return 'Folder name cannot end with a period'; 32783 } 32784 32785 return null; 32786} 32787 32788function updateFolderNameValidation(error) { 32789 const name = ($('#inputFolder').val() || '').trim(); 32790 const $error = $('#folder-name-error'); 32791 const $saveButton = $('#save-folder-button'); 32792 32793 if (error && name) { 32794 $error.text(error).removeClass('hidden'); 32795 } else { 32796 $error.text('').addClass('hidden'); 32797 } 32798 32799 $saveButton.prop('disabled', !!error); 32800} 32801 32802function resetFolderNameForm() { 32803 $('#inputFolder').val(''); 32804 $('#folder-name-error').text('').addClass('hidden'); 32805 $('#save-folder-button').prop('disabled', true); 32806} 32807 32808function getResizedUrl(url) { 32809 const path = url.replace('https://smpfiles.blob.core.windows.net', ''); 32810 return `https://resized-images.azureedge.net${path}?min=256`; 32811} 32812 32813function IsGlobalDirectorySelected() { 32814 return currentPath.startsWith('/uploads/global/'); 32815} 32816 32817function IsLogoDirectorySelected() { 32818 return currentPath.startsWith('/uploads/logos/'); 32819} 32820 32821function IsCollegeLogosDirectorySelected() { 32822 return collegeLogosPath !== '' && currentPath.startsWith(collegeLogosPath); 32823} 32824 32825function IsCurrentDirectoryEditable() { 32826 if (IsLogoDirectorySelected()) { 32827 return false; 32828 } 32829 if (IsGlobalDirectorySelected()) { 32830 return IsGlobalContentAdmin; 32831 } 32832 if (IsCollegeLogosDirectorySelected()) { 32833 return canEditCollegeLogos; 32834 } 32835 return true; 32836} 32837 32838function LoadFiles(path, page = 0, pageSize = 50) { 32839 $('[delete-file], [insert-file]').toggle(false); 32840 32841 currentPath = (path + "/").replace(/~\//, '/').replace(/\/\//, '/').replace(/%20/, ' '); 32842 32843 window.location.hash = currentPath; 32844 $('#directory').val(currentPath); 32845 32846 $('#Processing').toggle(true); 32847 UpdatePathBar(currentPath); 32848 32849 const search = $('.SearchText').val(); 32850 32851 fetch(`/api/file${path}${(search ? `?search=${search}&` : "?")}page=${page}&pageSize=${pageSize}`, 32852 { 32853 headers: { 'Content-Type': 'application/json' } 32854 }) 32855 .then((res) => { 32856 $('#Processing').toggle(false); 32857 32858 if (!res.ok) { 32859 console.warn(res); 32860 32861 if (res.status === 401) { 32862 $('#ListView').toggle(false); 32863 $('#LoggedOut').toggle(true); 32864 } 32865 32866 return; 32867 } 32868 32869 res.json().then(data => { 32870 32871 let directoriesHtml = []; 32872 let filesHtml = []; 32873 let month = null; 32874 let lastProgramName = null; 32875 var isLogoList = data.isLogoList; 32876 32877 $('[create-folder]').toggle(IsCurrentDirectoryEditable()); 32878 $('[toggle-file-upload-view]').toggle(IsCurrentDirectoryEditable()); 32879 32880 if (IsCurrentDirectoryEditable()) { 32881 filesHtml.push( 32882 `<div style="max-width: 275px;" class="Notice">Hold Ctrl to select multiple files</div>`); 32883 } 32884 32885 data.items 32886 .filter(i => i.isDirectory 32887 || (showDocs ? i.uri.match(/\.(zip|pdf|doc|docx|xls|xlsx|csv)$/i) 32888 : showVideos ? i.uri.match(/\.(mp4)$/i) 32889 : showImages ? i.uri.match(/\.(jpg|jpeg|png|gif|svg)$/i) 32890 : true)) 32891 .forEach(function (i) { 32892 const name = i.uri.split(/\//); 32893 const primary = i.uri.split(/\/uploads\//); 32894 32895 if (i.isDirectory) { 32896 directoriesHtml.push( 32897 `<li path='/uploads/${primary[primary.length - 1]}' > 32898 <i class='fa fa-folder'></i>
32899 <span>${i.customName || name[name.length - (i.uri.endsWith('/') ? 2 : 1)]}</span> 32900 </li>`); 32901 } else { 32902 let isImage = i.uri.match(/\.(jpg|jpeg|png|gif|svg)$/i); 32903 32904 if (i.createdUtc && !isLogoList) { 32905 const itemMonth = moment(i.createdUtc).format('MMMM YYYY'); 32906 if (month !== itemMonth) { 32907 month = itemMonth; 32908 32909 filesHtml.push( 32910 `<li class='month-header'> 32911 ${month} 32912 </li>` 32913 ); 32914 } 32915 } else if (isLogoList) { 32916 if (typeof i.programName !== 'undefined' && i.programName !== lastProgramName) { 32917 lastProgramName = i.programName; 32918 filesHtml.push( 32919 `<li class='month-header'> 32920 ${i.programName} 32921 </li>` 32922 ); 32923 } 32924 else if (typeof i.programName === 'undefined') { 32925 filesHtml.push( 32926 `<li class='month-header'> 32927 Main Logo 32928 </li>` 32929 ); 32930 } 32931 } 32932 32933 if (isImage) { 32934 filesHtml.push( 32935 `<li class='image-tile' path='${primary[primary.length - 1]}' > 32936 <div class='selection-shade'><i class='fa fa-check'></i></div> 32937 <img src='${getResizedUrl(i.uri)}' title='${name[name.length - 1]} ${(i.bytes / 1024).toFixed(0)}KB'/> 32938 </li>` 32939 ); 32940 } 32941 else { 32942 let icon = "<i class='fa fa-file' style='font-size: 48px;'></i>"; 32943 32944 if (i.uri.match(/\.pdf$/)) { 32945 icon = "<i class='fa fa-file-pdf' style='font-size: 48px;'></i>"; 32946 } else if (i.uri.match(/\.mp4$/)) { 32947 icon = "<i class='fa fa-video' style='font-size: 48px;'></i>"; 32948 } 32949 32950 filesHtml.push( 32951 `<li path='${primary[primary.length - 1]}' > 32952 <span class='FileIcon'>${icon}</span> 32953 <span class='FileInfo'> 32954 <div class='FileName'>${name[name.length - 1]}</span> 32955 <div class='FileSize'>${(i.bytes / 1024).toFixed(0)} KB</div> 32956 </span> 32957 </li>`); 32958 } 32959 } 32960 }); 32961 32962 if (filesHtml.length === 0 && !isLogoList) { 32963 filesHtml.push( 32964 `<div class="Notice" style="text-align:left;">
32964Folder contains no ${(showDocs ? 'docs' : showVideos ? 'video' : showImages ? 'images' : 'files')}${(search ? ` for search '${search}'` : '')}</div>`); 32965 } 32966 32967 if (directoriesHtml.length > 0) { 32968 $("#DirectoryList") 32969 .html(`<ul class='card-list flex top'>${directoriesHtml.join('\n')}</ul>`); 32970 } 32971 else { 32972 $("#DirectoryList").html(`<div class="Notice" style="text-align:left;">Folder contains no folders</div>`); 32973 } 32974 32975 if (page === 0) { 32976 $('#FileList').html(''); 32977 } 32978 var fileList = $('#FileList ul'); 32979 if (fileList.length === 0) { 32980 $('#FileList').html(`<ul class='flex'></ul>`); 32981 fileList = $('#FileList ul'); 32982 } 32983 32984 fileList.append(filesHtml.join('\n')); 32985 32986 $('#FileList [path]').on('click', function (event) { 32987 const wasSelected = $(this).hasClass('selected'); 32988 if (event.ctrlKey) { 32989 if (!wasSelected) { 32990 $(this).addClass('selected'); 32991 } 32992 else { 32993 $(this).removeClass('selected'); 32994 } 32995 } 32996 else { 32997 $("#FileList li").removeClass('selected'); 32998 if (!wasSelected) { 32999 $(this).addClass('selected'); 33000 } 33001 } 33002 33003 $('[delete-file]').toggle(IsCurrentDirectoryEditable() && $("#FileList li.selected").length > 0); 33004 $('[insert-file]').toggle(InsertEnabled === true && $("#FileList li.selected").length > 0); 33005 33006 }); 33007 33008 if (!window.top.opener && !window.top) { 33009 $('#FileList .InsertButton').css('display', 'none'); 33010 } 33011 $('#loadMore').toggle(data.hasMoreItems !== undefined && data.hasMoreItems && $("#brand-logos-li").hasClass('selected')); 33012 }); 33013 }) 33014 .catch(() => { 33015 $('#Processing').toggle(false); 33016 $.fn.modalAlert.open({ content: 'Failed to get listing' }); 33017 }); 33018} 33019 33020function UpdatePathBar(path) { 33021 if (path !== undefined && !IsLogoDirectorySelected()) { 33022 let pathArray = path.split('/').filter(i => i != ''); 33023 let breadcrumbs = []; 33024 let pathPart = "/"; 33025 const segmentCount = pathArray.length; 33026 const teamIndex = pathArray.indexOf('Team'); 33027 33028 for (index = 0; index < pathArray.length; index++) { 33029 pathPart += pathArray[index] + "/"; 33030 33031 let text = pathArray[index].replace("%20", " "); 33032 33033 if (index === 1) { 33034 const affiliationName = affiliationNames.find(a => a.id == pathArray[index])?.name; 33035 text = pathArray[index] === 'global' ? 'Global' : affiliationName; 33036 } 33037 33038 if (index == segmentCount - 1 33039 || (!isAdmin && index < teamIndex + 1) 33040 || (index === 1 && IsCollegeLogosDirectorySelected() && !canEditCollegeLogos)) { 33041 breadcrumbs.push(`<span class="breadcrumb-item">${text}</span>`); 33042 } else { 33043 breadcrumbs.push(`<a class="breadcrumb-item" onclick='LoadFiles("${pathPart}");'>${text}</a>`); 33044 } 33045 } 33046 33047 $("#FileManager .Breadcrumbs").html(breadcrumbs.join('\n')); 33048 33049 $('[delete-folder]').toggle(IsCurrentDirectoryEditable() && segmentCount > 2); 33050 } 33051} 33052 33053 33054function DeleteFile() { 33055 if ($("#FileList li.selected").length < 1) { 33056 $.fn.modalAlert.open({ content: "select one or more files" }); 33057 return; 33058 } 33059 33060 $.fn.modalConfirm.open({ 33061 content: 'Are you sure you want to delete the selected item(s)?', 33062 confirm: () => { 33063 $('#Processing').toggle(true); 33064 $("#FileList li.selected").each(function (index, element) { 33065 fetch(`/api/file/uploads/${$(element).attr('path')}`, 33066 { 33067 method: "DELETE", 33068 headers: { 'Content-Type': 'application/json' } 33069 }) 33070 .then((res) => { 33071 $('#Processing').toggle(false); 33072 if (!res.ok) { 33073 $.fn.modalAlert.open({ content: 'Failed to delete' }); 33074 } 33075 }) 33076 .catch(() => { 33077 $('#Processing').toggle(false); 33078 $.fn.modalAlert.open({ content: 'Failed to delete' }); 33079 }); 33080 }); 33081 LoadFiles(currentPath); 33082 } 33083 });
33084} 33085 33086function DeleteFolder() { 33087 $.fn.modalConfirm.open({ 33088 content: 'Are you sure you want to delete the current folder?', 33089 confirm: () => { 33090 $('#Processing').toggle(true); 33091 33092 fetch(`/api/file${currentPath}`, 33093 { 33094 method: "DELETE", 33095 headers: { 'Content-Type': 'application/json' } 33096 }) 33097 .then((res) => { 33098 $('#Processing').toggle(false); 33099 if (res.ok) { 33100 const segments = currentPath.split('/'); 33101 LoadFiles(segments.slice(0, segments.length - 2).join('/')); 33102 } 33103 else { 33104 res.json() 33105 .then((json) => $.fn.modalAlert.open({ content: json.message })) 33106 .catch((json) => $.fn.modalAlert.open({ content: 'Failed to delete' })); 33107 } 33108 }) 33109 .catch(() => { 33110 $('#Processing').toggle(false); 33111 $.fn.modalAlert.open({ content: 'Failed to delete' }); 33112 }); 33113 } 33114 }); 33115} 33116 33117; 33118////pf: node_modules/html2canvas/dist/html2canvas.min.js
vendor: 13,079 bytes, lines 33119-33138
33119/*! 33120 * html2canvas 1.4.1 <https://html2canvas.hertzen.com> 33121 * Copyright (c) 2022 Niklas von Hertzen <https://hertzen.com> 33122 * Released under MIT License 33123 */ 33124!function(A,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(A="undefined"!=typeof globalThis?globalThis:A||self).html2canvas=e()}(this,function(){"use strict"; 33125/*! ***************************************************************************** 33126 Copyright (c) Microsoft Corporation. 33127 33128 Permission to use, copy, modify, and/or distribute this software for any 33129 purpose with or without fee is hereby granted. 33130 33131 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 33132 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 33133 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 33134 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 33135 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 33136 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 33137 PERFORMANCE OF THIS SOFTWARE. 33138 ***************************************************************************** */var r=function(A,e){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(A,e){A.__proto__=e}||function(A,e){for(var t in e)Object.prototype.hasOwnProperty.call(e,t)&&(A[t]=e[t])})(A,e)};function A(A,e){if("function"!=typeof e&&null!==e)throw new TypeError("Class extends value "+String(e)+" is not a constructor or null");function t(){this.constructor=A}r(A,e),A.prototype=null===e?Object.create(e):(t.prototype=e.prototype,new t)}var h=function(){return(h=Object.assign||function(A){for(var e,t=1,r=arguments.length;t<r;t++)for(var B in e=arguments[t])Object.prototype.hasOwnProperty.call(e,B)&&(A[B]=e[B]);return A}).apply(this,arguments)};function a(A,s,o,i){return new(o=o||Promise)(function(t,e){function r(A){try{n(i.next(A))}catch(A){e(A)}}function B(A){try{n(i.throw(A))}catch(A){e(A)}}function n(A){var e;A.done?t(A.value):((e=A.value)instanceof o?e:new o(function(A){A(e)})).then(r,B)}n((i=i.apply(A,s||[])).next())})}function H(t,r){var B,n,s,o={label:0,sent:function(){if(1&s[0])throw s[1];return s[1]},trys:[],ops:[]},A={next:e(0),throw:e(1),return:e(2)};return"function"==typeof Symbol&&(A[Symbol.iterator]=function(){return this}),A;function e(e){return function(A){return function(e){if(B)throw new TypeError("Generator is already executing.");for(;o;)try{if(B=1,n&&(s=2&e[0]?n.return:e[0]?n.throw||((s=n.return)&&s.call(n),0):n.next)&&!(s=s.call(n,e[1])).done)return s;switch(n=0,(e=s?[2&e[0],s.value]:e)[0]){case 0:case 1:s=e;break;case 4:return o.label++,{value:e[1],done:!1};case 5:o.label++,n=e[1],e=[0];continue;case 7:e=o.ops.pop(),o.trys.pop();continue;default:if(!(s=0<(s=o.trys).length&&s[s.length-1])&&(6===e[0]||2===e[0])){o=0;continue}if(3===e[0]&&(!s||e[1]>s[0]&&e[1]<s[3])){o.label=e[1];break}if(6===e[0]&&o.label<s[1]){o.label=s[1],s=e;break}if(s&&o.label<s[2]){o.label=s[2],o.ops.push(e);break}s[2]&&o.ops.pop(),o.trys.pop();continue}e=r.call(t,o)}catch(A){e=[6,A],n=0}finally{B=s=0}if(5&e[0])throw e[1];return{value:e[0]?e[1]:void 0,done:!0}}([e,A])}}}function t(A,e,t){if(t||2===arguments.length)for(var r,B=0,n=e.length;B<n;B++)!r&&B in e||((r=r||Array.prototype.slice.call(e,0,B))[B]=e[B]);return A.concat(r||e)}var d=(B.prototype.add=function(A,e,t,r){return new B(this.left+A,this.top+e,this.width+t,this.height+r)},B.fromClientRect=function(A,e){return new B(e.left+A.windowBounds.left,e.top+A.windowBounds.top,e.width,e.height)},B.fromDOMRectList=function(A,e){e=Array.from(e).find(function(A){return 0!==A.width});return e?new B(e.left+A.windowBounds.left,e.top+A.windowBounds.top,e.width,e.height):B.EMPTY},B.EMPTY=new B(0,0,0,0),B);function B(A,e,t,r){this.left=A,this.top=e,this.width=t,this.height=r}for(var f=function(A,e){return d.fromClientRect(A,e.getBoundingClientRect())},Q=function(A){for(var e=[],t=0,r=A.length;t<r;){var B,n=A.charCodeAt(t++);55296<=n&&n<=56319&&t<r?56320==(64512&(B=A.charCodeAt(t++)))?e.push(((1023&n)<<10)+(1023&B)+65536):(e.push(n),t--):e.push(n)}return e},g=function(){for(var A=[],e=0;e<arguments.length;e++)A[e]=arguments[e];if(String.fromCodePoint)return String.fromCodePoint.apply(String,A);var t=A.length;if(!t)return"";for(var r=[],B=-1,n="";++B<t;){var s=A[B];s<=65535?r.push(s):(s-=65536,r.push(55296+(s>>10),s%1024+56320)),(B+1===t||16384<r.length)&&(n+=String.fromCharCode.apply(String,r),r.length=0)}return n},e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",n="undefined"==typeof Uint8Array?[]:new Uint8Array(256),s=0;s<e.length;s++)n[e.charCodeAt(s)]=s;for(var o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",c="undefined"==typeof Uint8Array?[]:new Uint8Array(256),i=0;i<o.length;i++)c[o.charCodeAt(i)]=i;function w(A,e,t){return A.slice?A.slice(e,t):new Uint16Array(Array.prototype.slice.call(A,e,t))}var U=(l.prototype.get=function(A){var e;if(0<=A){if(A<55296||56319<A&&A<=65535)return e=this.index[A>>5],this.data[e=(e<<2)+(31&A)];if(A<=65535)return e=this.index[2048+(A-55296>>5)],this.data[e=(e<<2)+(31&A)];if(A<this.highStart)return e=this.index[e=2080+(A>>11)],e=this.index[e+=A>>5&63],this.data[e=(e<<2)+(31&A)];if(A<=1114111)return this.data[this.highValueIndex]}return this.errorValue},l);function l(A,e,t,r,B,n){this.initialValue=A,this.errorValue=e,this.highStart=t,this.highValueIndex=r,this.index=B,this.data=n}for(var C="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",u="undefined"==typeof Uint8Array?[]:new Uint8Array(256),F=0;F<C.length;F++)u[C.charCodeAt(F)]=F;function p(A,e,t,r){var B=r[t];if(Array.isArray(A)?-1!==A.indexOf(B):A===B)for(var n=t;n<=r.length;){if((o=r[++n])===e)return 1;if(o!==D)break}if(B===D)for(n=t;0<n;){var s=r[--n];if(Array.isArray(A)?-1!==A.indexOf(s):A===s)for(var o,i=t;i<=r.length;){if((o=r[++i])===e)return 1;if(o!==D)break}if(s!==D)break}}function E(A,e){for(var t=A;0<=t;){var r=e[t];if(r!==D)return r;t--}return 0}function I(t,A){var e=(B=function(A,r){void 0===r&&(r="strict");var B=[],n=[],s=[];return A.forEach(function(A,e){var t=rA.get(A);if(50<t?(s.push(!0),t-=50):s.push(!1),-1!==["normal","auto","loose"].indexOf(r)&&-1!==[8208,8211,12316,12448].indexOf(A))return n.push(e),B.push(16);if(4!==t&&11!==t)return n.push(e),31===t?B.push("strict"===r?O:q):t===AA||29===t?B.push(J):43===t?131072<=A&&A<=196605||196608<=A&&A<=262141?B.push(q):B.push(J):void B.push(t);if(0===e)return n.push(e),B.push(J);t=B[e-1];return-1===iA.indexOf(t)?(n.push(n[e-1]),B.push(t)):(n.push(e),B.push(J))}),[n,B,s]}(t,(A=A||{lineBreak:"normal",wordBreak:"normal"}).lineBreak))[0],r=B[1],B=B[2];return[e,r="break-all"===A.wordBreak||"break-word"===A.wordBreak?r.map(function(A){return-1!==[R,J,AA].indexOf(A)?q:A}):r,"keep-all"===A.wordBreak?B.map(function(A,e){return A&&19968<=t[e]&&t[e]<=40959}):void 0]}var y,K,m,L,b,D=10,v=13,x=15,M=17,S=18,T=19,G=20,O=21,V=22,k=24,R=25,N=26,P=27,X=28,J=30,Y=32,W=33,Z=34,_=35,q=37,j=38,z=39,$=40,AA=42,eA=[9001,65288],tA="Ã",rA=(m=function(A){var e,t,r,B,n=.75*A.length,s=A.length,o=0;"="===A[A.length-1]&&(n--,"="===A[A.length-2]&&n--);for(var n=new("undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array&&void 0!==Uint8Array.prototype.slice?ArrayBuffer:Array)(n),i=Array.isArray(n)?n:new Uint8Array(n),Q=0;Q<s;Q+=4)e=c[A.charCodeAt(Q)],t=c[A.charCodeAt(Q+1)],r=c[A.charCodeAt(Q+2)],B=c[A.charCodeAt(Q+3)],i[o++]=e<<2|t>>4,i[o++]=(15&t)<<4|r>>2,i[o++]=(3&r)<<6|63&B;return n}(y="KwAAAAAAAAAACA4AUD0AADAgAAACAAAAAAAIABAAGABAAEgAUABYAGAAaABgAGgAYgBqAF8AZwBgAGgAcQB5AHUAfQCFAI0AlQCdAKIAqgCyALoAYABoAGAAaABgAGgAwgDKAGAAaADGAM4A0wDbAOEA6QDxAPkAAQEJAQ8BFwF1AH0AHAEkASwBNAE6AUIBQQFJAVEBWQFhAWgBcAF4ATAAgAGGAY4BlQGXAZ8BpwGvAbUBvQHFAc0B0wHbAeMB6wHxAfkBAQIJAvEBEQIZAiECKQIxAjgCQAJGAk4CVgJeAmQCbAJ0AnwCgQKJApECmQKgAqgCsAK4ArwCxAIwAMwC0wLbAjAA4wLrAvMC+AIAAwcDDwMwABcDHQMlAy0DNQN1AD0DQQNJA0kDSQNRA1EDVwNZA1kDdQB1AGEDdQBpA20DdQN1AHsDdQCBA4kDkQN1AHUAmQOhA3UAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AKYDrgN1AHUAtgO+A8YDzgPWAxcD3gPjA+sD8wN1AHUA+wMDBAkEdQANBBUEHQQlBCoEFwMyBDgEYABABBcDSARQBFgEYARoBDAAcAQzAXgEgASIBJAEdQCXBHUAnwSnBK4EtgS6BMIEyAR1AHUAdQB1AHUAdQCVANAEYABgAGAAYABgAGAAYABgANgEYADcBOQEYADsBPQE/AQEBQwFFAUcBSQFLAU0BWQEPAVEBUsFUwVbBWAAYgVgAGoFcgV6BYIFigWRBWAAmQWfBaYFYABgAGAAYABgAKoFYACxBbAFuQW6BcEFwQXHBcEFwQXPBdMF2wXjBeoF8gX6BQIGCgYSBhoGIgYqBjIGOgZgAD4GRgZMBmAAUwZaBmAAYABgAGAAYABgAGAAYABgAGAAYABgAGIGYABpBnAGYABgAGAAYABgAGAAYABgAGAAYAB4Bn8GhQZgAGAAYAB1AHcDFQSLBmAAYABgAJMGdQA9A3UAmwajBqsGqwaVALMGuwbDBjAAywbSBtIG1QbSBtIG0gbSBtIG0gbdBuMG6wbzBvsGAwcLBxMHAwcbByMHJwcsBywHMQcsB9IGOAdAB0gHTgfSBkgHVgfSBtIG0gbSBtIG0gbSBtIG0gbSBiwHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAdgAGAALAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAdbB2MHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsB2kH0gZwB64EdQB1AHUAdQB1AHUAdQB1AHUHfQdgAIUHjQd1AHUAlQedB2AAYAClB6sHYACzB7YHvgfGB3UAzgfWBzMB3gfmB1EB7gf1B/0HlQENAQUIDQh1ABUIHQglCBcDLQg1CD0IRQhNCEEDUwh1AHUAdQBbCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIcAh3CHoIMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIgggwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAALAcsBywHLAcsBywHLAcsBywHLAcsB4oILAcsB44I0gaWCJ4Ipgh1AHUAqgiyCHUAdQB1AHUAdQB1AHUAdQB1AHUAtwh8AXUAvwh1AMUIyQjRCNkI4AjoCHUAdQB1AO4I9gj+CAYJDgkTCS0HGwkjCYIIggiCCI
vendor: 4,489 bytes, line 33138
33138IIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiAAIAAAAFAAYABgAGIAXwBgAHEAdQBFAJUAogCyAKAAYABgAEIA4ABGANMA4QDxAMEBDwE1AFwBLAE6AQEBUQF4QkhCmEKoQrhCgAHIQsAB0MLAAcABwAHAAeDC6ABoAHDCwMMAAcABwAHAAdDDGMMAAcAB6MM4wwjDWMNow3jDaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAEjDqABWw6bDqABpg6gAaABoAHcDvwOPA+gAaABfA/8DvwO/A78DvwO/A78DvwO/A78DvwO/A78DvwO/A78DvwO/A78DvwO/A78DvwO/A78DvwO/A78DpcPAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcAB9cPKwkyCToJMAB1AHUAdQBCCUoJTQl1AFUJXAljCWcJawkwADAAMAAwAHMJdQB2CX4JdQCECYoJjgmWCXUAngkwAGAAYABxAHUApgn3A64JtAl1ALkJdQDACTAAMAAwADAAdQB1AHUAdQB1AHUAdQB1AHUAowYNBMUIMAAwADAAMADICcsJ0wnZCRUE4QkwAOkJ8An4CTAAMAB1AAAKvwh1AAgKDwoXCh8KdQAwACcKLgp1ADYKqAmICT4KRgowADAAdQB1AE4KMAB1AFYKdQBeCnUAZQowADAAMAAwADAAMAAwADAAMAAVBHUAbQowADAAdQC5CXUKMAAwAHwBxAijBogEMgF9CoQKiASMCpQKmgqIBKIKqgquCogEDQG2Cr4KxgrLCjAAMADTCtsKCgHjCusK8Qr5CgELMAAwADAAMAB1AIsECQsRC3UANAEZCzAAMAAwADAAMAB1ACELKQswAHUANAExCzkLdQBBC0kLMABRC1kLMAAwADAAMAAwADAAdQBhCzAAMAAwAGAAYABpC3ELdwt/CzAAMACHC4sLkwubC58Lpwt1AK4Ltgt1APsDMAAwADAAMAAwADAAMAAwAL4LwwvLC9IL1wvdCzAAMADlC+kL8Qv5C/8LSQswADAAMAAwADAAMAAwADAAMAAHDDAAMAAwADAAMAAODBYMHgx1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1ACYMMAAwADAAdQB1AHUALgx1AHUAdQB1AHUAdQA2DDAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AD4MdQBGDHUAdQB1AHUAdQB1AEkMdQB1AHUAdQB1AFAMMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQBYDHUAdQB1AF8MMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUA+wMVBGcMMAAwAHwBbwx1AHcMfwyHDI8MMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAYABgAJcMMAAwADAAdQB1AJ8MlQClDDAAMACtDCwHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsB7UMLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AA0EMAC9DDAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAsBywHLAcsBywHLAcsBywHLQcwAMEMyAwsBywHLAcsBywHLAcsBywHLAcsBywHzAwwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAHUAdQB1ANQM2QzhDDAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMABgAGAAYABgAGAAYABgAOkMYADxDGAA+AwADQYNYABhCWAAYAAODTAAMAAwADAAFg1gAGAAHg37AzAAMAAwADAAYABgACYNYAAsDTQNPA1gAEMNPg1LDWAAYABgAGAAYABgAGAAYABgAGAAUg1aDYsGVglhDV0NcQBnDW0NdQ15DWAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAlQCBDZUAiA2PDZcNMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAnw2nDTAAMAAwADAAMAAwAHUArw23DTAAMAAwADAAMAAwADAAMAAwADAAMAB1AL8NMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAB1AHUAdQB1AHUAdQDHDTAAYABgAM8NMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAA1w11ANwNMAAwAD0B5A0wADAAMAAwADAAMADsDfQN/A0EDgwOFA4wABsOMAAwADAAMAAwADAAMAAwANIG0gbSBtIG0gbSBtIG0gYjDigOwQUuDsEFMw7SBjoO0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIGQg5KDlIOVg7SBtIGXg5lDm0OdQ7SBtIGfQ6EDooOjQ6UDtIGmg6hDtIG0gaoDqwO0ga0DrwO0gZgAGAAYADEDmAAYAAkBtIGzA5gANIOYADaDokO0gbSBt8O5w7SBu8O0gb1DvwO0gZgAGAAxA7SBtIG0gbSBtIGYABgAGAAYAAED2AAsAUMD9IG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIGFA8sBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAccD9IGLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHJA8sByw
vendor: 15,579 bytes, line 33138
33138HLAcsBywHLAccDywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywPLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAc0D9IG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIGLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAccD9IG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIGFA8sBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHPA/SBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gYUD0QPlQCVAJUAMAAwADAAMACVAJUAlQCVAJUAlQCVAEwPMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAA//8EAAQABAAEAAQABAAEAAQABAANAAMAAQABAAIABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQACgATABcAHgAbABoAHgAXABYAEgAeABsAGAAPABgAHABLAEsASwBLAEsASwBLAEsASwBLABgAGAAeAB4AHgATAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQABYAGwASAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAWAA0AEQAeAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAAQABAAEAAQABAAFAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAJABYAGgAbABsAGwAeAB0AHQAeAE8AFwAeAA0AHgAeABoAGwBPAE8ADgBQAB0AHQAdAE8ATwAXAE8ATwBPABYAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAFAAUABQAFAAUABQAFAAUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAB4AHgAeAFAATwBAAE8ATwBPAEAATwBQAFAATwBQAB4AHgAeAB4AHgAeAB0AHQAdAB0AHgAdAB4ADgBQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgBQAB4AUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAJAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAkACQAJAAkACQAJAAkABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAeAB4AHgAeAFAAHgAeAB4AKwArAFAAUABQAFAAGABQACsAKwArACsAHgAeAFAAHgBQAFAAUAArAFAAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAEAAQABAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAUAAeAB4AHgAeAB4AHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAYAA0AKwArAB4AHgAbACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQADQAEAB4ABAAEAB4ABAAEABMABAArACsAKwArACsAKwArACsAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAKwArACsAKwBWAFYAVgBWAB4AHgArACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AGgAaABoAGAAYAB4AHgAEAAQABAAEAAQABAAEAAQABAAEAAQAEwAEACsAEwATAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABLAEsASwBLAEsASwBLAEsASwBLABoAGQAZAB4AUABQAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQABMAUAAEAAQABAAEAAQABAAEAB4AHgAEAAQABAAEAAQABABQAFAABAAEAB4ABAAEAAQABABQAFAASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUAAeAB4AUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAFAABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQAUABQAB4AHgAYABMAUAArACsABAAbABsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAFAABAAEAAQABAAEAFAABAAEAAQAUAAEAAQABAAEAAQAKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAArACsAHgArAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAB4ABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAUAAEAAQABAAEAAQABAAEAFAAUABQAFAAUABQAFAAUABQAFAABAAEAA0ADQBLAEsASwBLAEsASwBLAEsASwBLAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAArAFAAUABQAFAAUABQAFAAUAArACsAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUAArACsAKwBQAFAAUABQACsAKwAEAFAABAAEAAQABAAEAAQABAArACsABAAEACsAKwAEAAQABABQACsAKwArACsAKwArACsAKwAEACsAKwArACsAUABQACsAUABQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLAFAAUAAaABoAUABQAFAAUABQAEwAHgAbAFAAHgAEACsAKwAEAAQABAArAFAAUABQAFAAUABQACsAKwArACsAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUABQACsAUABQACsAUABQACsAKwAEACsABAAEAAQABAAEACsAKwArACsABAAEACsAKwAEAAQABAArACsAKwAEACsAKwArACsAKwArACsAUABQAFAAUAArAFAAKwArACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLAAQABABQAFAAUAAEAB4AKwArACsAKwArACsAKwArACsAKwAEAAQABAArAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUABQACsAUABQAFAAUABQACsAKwAEAFAABAAEAAQABAAEAAQABAAEACsABAAEAAQAKwAEAAQABAArACsAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLAB4AGwArACsAKwArACsAKwArAFAABAAEAAQABAAEAAQAKwAEAAQABAArAFAAUABQAFAAUABQAFAAUAArACsAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAArACsABAAEACsAKwAEAAQABAArACsAKwArACsAKwArAAQABAAEACsAKwArACsAUABQACsAUABQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLAB4AUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArAAQAUAArAFAAUABQAFAAUABQACsAKwArAFAAUABQACsAUABQAFAAUAArACsAKwBQAFAAKwBQACsAUABQACsAKwArAFAAUAArACsAKwBQAFAAUAArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArAAQABAAEAAQABAArACsAKwAEAAQABAArAAQABAAEAAQAKwArAFAAKwArACsAKwArACsABAArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAUABQAFAAHgAeAB4AHgAeAB4AGwAeACsAKwArACsAKwAEAAQABAAEAAQAUABQAFAAUABQAFAAUABQACsAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAUAAEAAQABAAEAAQABAAEACsABAAEAAQAKwAEAAQABAAEACsAKwArACsAKwArACsABAAEACsAUABQAFAAKwArACsAKwArAFAAUAAEAAQAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAKwAOAFAAUABQAFAAUABQAFAAHgBQAAQABAAEAA4AUABQAFAAUABQAFAAUABQACsAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAKwArAAQAUAAEAAQABAAEAAQABAAEACsABAAEAAQAKwAEAAQABAAEACsAKwArACsAKwArACsABAAEACsAKwArACsAKwArACsAUAArAFAAUAAEAAQAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwBQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwAEAAQABAAEAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAFAABAAEAAQABAAEAAQABAArAAQABAAEACsABAAEAAQABABQAB4AKwArACsAKwBQAFAAUAAEAFAAUABQAFAAUABQAFAAUABQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLAFAAUABQAFAAUABQAFAAUABQABoAUABQAFAAUABQAFAAKwAEAAQABAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQACsAUAArACsAUABQAFAAUABQAFAAUAArACsAKwAEACsAKwArACsABAAEAAQABAAEAAQAKwAEACsABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArAAQABAAeACsAKwArACsAKwArACsAKwArACsAKwArAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAAqAFwAXAAqACoAKgAqACoAKgAqACsAKwArACsAGwBcAFwAXABcAFwAXABcACoAKgAqACoAKgAqACoAKgAeAEsASwBLAEsASwBLAEsASwBLAEsADQANACsAKwArACsAKwBcAFwAKwBcACsAXABcAFwAXABcACsAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcACsAXAArAFwAXABcAFwAXABcAFwAXABcAFwAKgBcAFwAKgAqACoAKgAqACoAKgAqACoAXAArACsAXABcAFwAXABcACsAXAArACoAKgAqACoAKgAqACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwBcAFwAXABcAFAADgAOAA4ADgAeAA4ADgAJAA4ADgANAAkAEwATABMAEwATAAkAHgATAB4AHgAeAAQABAAeAB4AHgAeAB4AHgBLAEsASwBLAEsASwBLAEsASwBLAFAAUABQAFAAUABQAFAAUABQAFAADQAEAB4ABAAeAAQAFgARABYAEQAEAAQAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQADQAEAAQABAAEAAQADQAEAAQAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArAA0ADQAeAB4AHgAeAB4AHgAEAB4AHgAeAB4AHgAeACsAHgAeAA4ADgANAA4AHgAeAB4AHgAeAAkACQArACsAKwArACsAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgBcAEsASwBLAEsASwBLAEsASwBLAEsADQANAB4AHgAeAB4AXABcAFwAXABcAFwAKgAqACoAKgBcAFwAXABcACoAKgAqAFwAKgAqACoAXABcACoAKgAqACoAKgAqACoAXABcAFwAKgAqACoAKgBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcACoAKgAqACoAKgAqACoAKgAqACoAKgAqAFwAKgBLAEsASwBLAEsASwBLAEsASwBLACoAKgAqACoAKgAqAFAAUABQAFAAUABQACsAUAArACsAKwArACsAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgBQAFAAUABQAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUAArACsAUABQAFAAUABQAFAAUAArAFAAKwBQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAKwBQACsAUABQAFAAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsABAAEAAQAHgANAB4AHgAeAB4AHgAeAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUAArACsADQBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAANAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAWABEAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAA0ADQANAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAAQABAAEACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAANAA0AKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUAArAAQABAArACsAKwArACsAKwArACsAKwArACsAKwBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqAA0ADQAVAFwADQAeAA0AGwBcACoAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwAeAB4AEwATAA0ADQAOAB4AEwATAB4ABAAEAAQACQArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAFAAUABQAFAAUAAEAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQAUAArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAHgArACsAKwATABMASwBLAEsASwBLAEsASwBLAEsASwBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAArACsAXABcAFwAXABcACsAKwArACsAKwArACsAKwArACsAKwBcAFwAXABcAFwAXABcAFwAXABcAFwAXAArACsAKwArAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAXAArACsAKwAqACoAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAArACsAHgAeAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcACoAKgAqACoAKgAqACoAKgAqACoAKwAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKwArAAQASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAKwArACoAKgAqACoAKgAqACoAXAAqACoAKgAqACoAKgArACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsABAAEAAQABAAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABABQAFAAUABQAFAAUABQACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwANAA0AHgANAA0ADQANAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAEAAQABAAEAAQAHgAeAB4AHgAeAB4AHgAeAB4AKwArACsABAAEAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABQAFAASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwAeAB4AHgAeAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArAA0ADQANAA0ADQBLAEsASwBLAEsASwBLAEsASwBLACsAKwArAFAAUABQAEsASwBLAEsASwBLAEsASwBLAEsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAA0ADQBQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUAAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArAAQABAAEAB4ABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAAQAUABQAFAAUABQAFAABABQAFAABAAEAAQAUAArACsAKwArACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsABAAEAAQABAAEAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArAFAAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAKwBQACsAUAArAFAAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAB4AHgAeAB4AHgAeAB4AHgBQAB4AHgAeAFAAUABQACsAHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAUABQACsAKwAeAB4AHgAeAB4AHgArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArAFAAUABQACsAHgAeAB4AHgAeAB4AHgAOAB4AKwANAA0ADQANAA0ADQANAAkADQANAA0ACAAEAAsABAAEAA0ACQANAA0ADAAdAB0AHgAXABcAFgAXABcAFwAWABcAHQAdAB4AHgAUABQAFAANAAEAAQAEAAQABAAEAAQACQAaABoAGgAaABoAGgAaABoAHgAXABcAHQAVABUAHgAeAB4AHgAeAB4AGAAWABEAFQAVABUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ADQAeAA0ADQANAA0AHgANAA0ADQAHAB4AHgAeAB4AKwAEAAQABAAEAAQABAAEAAQABAAEAFAAUAArACsATwBQAFAAUABQAFAAHgAeAB4AFgARAE8AUABPAE8ATwBPAFAAUABQAFAAUAAeAB4AHgAWABEAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArABsAGwAbABsAGwAbABsAGgAbABsAGwAbABsAGwAbABsAGwAbABsAGwAbABsAGgAbABsAGwAbABoAGwAbABoAGwAbABsAGwAbABsAGwAbABsAGwAbABsAGwAbABsAGwAbAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAHgAeAFAAGgAeAB0AHgBQAB4AGgAeAB4AHgAeAB4AHgAeAB4AHgBPAB4AUAAbAB4AHgBQAFAAUABQAFAAHgAeAB4AHQAdAB4AUAAeAFAAHgBQAB4AUABPAFAAUAAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAHgBQAFAAUABQAE8ATwBQAFAAUABQAFAATwBQAFAATwBQAE8ATwBPAE8ATw
vendor: 5,424 bytes, line 33138
33138BPAE8ATwBPAE8ATwBPAFAAUABQAFAATwBPAE8ATwBPAE8ATwBPAE8ATwBQAFAAUABQAFAAUABQAFAAUAAeAB4AUABQAFAAUABPAB4AHgArACsAKwArAB0AHQAdAB0AHQAdAB0AHQAdAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHgAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB4AHQAdAB4AHgAeAB0AHQAeAB4AHQAeAB4AHgAdAB4AHQAbABsAHgAdAB4AHgAeAB4AHQAeAB4AHQAdAB0AHQAeAB4AHQAeAB0AHgAdAB0AHQAdAB0AHQAeAB0AHgAeAB4AHgAeAB0AHQAdAB0AHgAeAB4AHgAdAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB4AHgAeAB0AHgAeAB4AHgAeAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB0AHgAeAB0AHQAdAB0AHgAeAB0AHQAeAB4AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHQAeAB4AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAeAB4AHgAdAB4AHgAeAB4AHgAeAB4AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AFAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeABYAEQAWABEAHgAeAB4AHgAeAB4AHQAeAB4AHgAeAB4AHgAeACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAWABEAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAFAAHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHgAeAB4AHgAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAeAB4AHQAdAB0AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHQAeAB0AHQAdAB0AHQAdAB0AHgAeAB4AHgAeAB4AHgAeAB0AHQAeAB4AHQAdAB4AHgAeAB4AHQAdAB4AHgAeAB4AHQAdAB0AHgAeAB0AHgAeAB0AHQAdAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB0AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAlAB4AHQAdAB4AHgAdAB4AHgAeAB4AHQAdAB4AHgAeAB4AJQAlAB0AHQAlAB4AJQAlACUAIAAlACUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAeAB4AHgAeAB0AHgAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB0AHgAdAB0AHQAeAB0AJQAdAB0AHgAdAB0AHgAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAlACUAJQAlACUAJQAlACUAJQAdAB0AHQAdACUAHgAlACUAJQAdACUAJQAdAB0AHQAlACUAHQAdACUAHQAdACUAJQAlAB4AHQAeAB4AHgAeAB0AHQAlAB0AHQAdAB0AHQAdACUAJQAlACUAJQAdACUAJQAgACUAHQAdACUAJQAlACUAJQAlACUAJQAeAB4AHgAlACUAIAAgACAAIAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHgAeAB4AFwAXABcAFwAXABcAHgATABMAJQAeAB4AHgAWABEAFgARABYAEQAWABEAFgARABYAEQAWABEATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeABYAEQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAWABEAFgARABYAEQAWABEAFgARAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AFgARABYAEQAWABEAFgARABYAEQAWABEAFgARABYAEQAWABEAFgARABYAEQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAWABEAFgARAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AFgARAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB0AHQAdAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AUABQAFAAUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAEAAQABAAeAB4AKwArACsAKwArABMADQANAA0AUAATAA0AUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAUAANACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAA0ADQANAA0ADQANAA0ADQAeAA0AFgANAB4AHgAXABcAHgAeABcAFwAWABEAFgARABYAEQAWABEADQANAA0ADQATAFAADQANAB4ADQANAB4AHgAeAB4AHgAMAAwADQANAA0AHgANAA0AFgANAA0ADQANAA0ADQANAA0AHgANAB4ADQANAB4AHgAeACsAKwArACsAKwArACsAKwArACsAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAKwArACsAKwArACsAKwArACsAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAlACUAJQAlACUAJQAlACUAJQAlACUAJQArACsAKwArAA0AEQARACUAJQBHAFcAVwAWABEAFgARABYAEQAWABEAFgARACUAJQAWABEAFgARABYAEQAWABEAFQAWABEAEQAlAFcAVwBXAFcAVwBXAFcAVwBXAAQABAAEAAQABAAEACUAVwBXAFcAVwA2ACUAJQBXAFcAVwBHAEcAJQAlACUAKwBRAFcAUQBXAFEAVwBRAFcAUQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFEAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBRAFcAUQBXAFEAVwBXAFcAVwBXAFcAUQBXAFcAVwBXAFcAVwBRAFEAKwArAAQABAAVABUARwBHAFcAFQBRAFcAUQBXAFEAVwBRAFcAUQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFEAVwBRAFcAUQBXAFcAVwBXAFcAVwBRAFcAVwBXAFcAVwBXAFEAUQBXAFcAVwBXABUAUQBHAEcAVwArACsAKwArACsAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwAlACUAVwBXAFcAVwAlACUAJQAlACUAJQAlACUAJQAlACsAKwArACsAKwArACsAKwArACsAKwArAFEAUQBRAFEAUQBRAFEAUQBRAFEAUQBRAFEAUQBRAFEAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQArAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQBPAE8ATw
vendor: 16,384 bytes, line 33138
33138BPAE8ATwBPAE8AJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQAlAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAEcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAADQATAA0AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABLAEsASwBLAEsASwBLAEsASwBLAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAABAAEAAQABAAeAAQABAAEAAQABAAEAAQABAAEAAQAHgBQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AUABQAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAeAA0ADQANAA0ADQArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAB4AHgAeAB4AHgAeAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAHgAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAeAB4AUABQAFAAUABQAFAAUABQAFAAUABQAAQAUABQAFAABABQAFAAUABQAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAeAB4AHgAeAAQAKwArACsAUABQAFAAUABQAFAAHgAeABoAHgArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAADgAOABMAEwArACsAKwArACsAKwArACsABAAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwANAA0ASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAFAAUAAeAB4AHgBQAA4AUABQAAQAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAA0ADQBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwArACsAKwArACsAKwArAB4AWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYACsAKwArAAQAHgAeAB4AHgAeAB4ADQANAA0AHgAeAB4AHgArAFAASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArAB4AHgBcAFwAXABcAFwAKgBcAFwAXABcAFwAXABcAFwAXABcAEsASwBLAEsASwBLAEsASwBLAEsAXABcAFwAXABcACsAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArAFAAUABQAAQAUABQAFAAUABQAFAAUABQAAQABAArACsASwBLAEsASwBLAEsASwBLAEsASwArACsAHgANAA0ADQBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKgAqACoAXAAqACoAKgBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAAqAFwAKgAqACoAXABcACoAKgBcAFwAXABcAFwAKgAqAFwAKgBcACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFwAXABcACoAKgBQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAA0ADQBQAFAAUAAEAAQAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUAArACsAUABQAFAAUABQAFAAKwArAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQADQAEAAQAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAVABVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBUAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVACsAKwArACsAKwArACsAKwArACsAKwArAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAKwArACsAKwBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAKwArACsAKwAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAKwArACsAKwArAFYABABWAFYAVgBWAFYAVgBWAFYAVgBWAB4AVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgArAFYAVgBWAFYAVgArAFYAKwBWAFYAKwBWAFYAKwBWAFYAVgBWAFYAVgBWAFYAVgBWAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAEQAWAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUAAaAB4AKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAGAARABEAGAAYABMAEwAWABEAFAArACsAKwArACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACUAJQAlACUAJQAWABEAFgARABYAEQAWABEAFgARABYAEQAlACUAFgARACUAJQAlACUAJQAlACUAEQAlABEAKwAVABUAEwATACUAFgARABYAEQAWABEAJQAlACUAJQAlACUAJQAlACsAJQAbABoAJQArACsAKwArAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAcAKwATACUAJQAbABoAJQAlABYAEQAlACUAEQAlABEAJQBXAFcAVwBXAFcAVwBXAFcAVwBXABUAFQAlACUAJQATACUAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXABYAJQARACUAJQAlAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwAWACUAEQAlABYAEQARABYAEQARABUAVwBRAFEAUQBRAFEAUQBRAFEAUQBRAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAEcARwArACsAVwBXAFcAVwBXAFcAKwArAFcAVwBXAFcAVwBXACsAKwBXAFcAVwBXAFcAVwArACsAVwBXAFcAKwArACsAGgAbACUAJQAlABsAGwArAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwAEAAQABAAQAB0AKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsADQANAA0AKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAB4AHgAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAAQAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAA0AUABQAFAAUAArACsAKwArAFAAUABQAFAAUABQAFAAUAANAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwAeACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAKwArAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUAArACsAKwBQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwANAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAB4AUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUAArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAA0AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAUABQAFAAUABQAAQABAAEACsABAAEACsAKwArACsAKwAEAAQABAAEAFAAUABQAFAAKwBQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAQABAAEACsAKwArACsABABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAA0ADQANAA0ADQANAA0ADQAeACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAFAAUABQAFAAUABQAFAAUAAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAArACsAKwArAFAAUABQAFAAUAANAA0ADQANAA0ADQAUACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsADQANAA0ADQANAA0ADQBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAFAAUABQAFAAUABQAAQABAAEAAQAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUAArAAQABAANACsAKwBQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAB4AHgAeAB4AHgArACsAKwArACsAKwAEAAQABAAEAAQABAAEAA0ADQAeAB4AHgAeAB4AKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAAeAB4AHgANAA0ADQANACsAKwArACsAKwArACsAKwArACsAKwAeACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAKwArAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsASwBLAEsASwBLAEsASwBLAEsASwANAA0ADQANAFAABAAEAFAAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAeAA4AUAArACsAKwArACsAKwArACsAKwAEAFAAUABQAFAADQANAB4ADQAEAAQABAAEAB4ABAAEAEsASwBLAEsASwBLAEsASwBLAEsAUAAOAFAADQANAA0AKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAANAA0AHgANAA0AHgAEACsAUABQAFAAUABQAFAAUAArAFAAKwBQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAA0AKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsABAAEAAQABAArAFAAUABQAFAAUABQAFAAUAArACsAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUABQACsAUABQAFAAUABQACsABAAEAFAABAAEAAQABAAEAAQABAArACsABAAEACsAKwAEAAQABAArACsAUAArACsAKwArACsAKwAEACsAKwArACsAKwBQAFAAUABQAFAABAAEACsAKwAEAAQABAAEAAQABAAEACsAKwArAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwArACsABAAEAAQABAAEAAQABABQAFAAUABQAA0ADQANAA0AHgBLAEsASwBLAEsASwBLAEsASwBLAA0ADQArAB4ABABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAEAAQABAAEAFAAUAAeAFAAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAArACsABAAEAAQABAAEAAQABAAEAAQADgANAA0AEwATAB4AHgAeAA0ADQANAA0ADQANAA0ADQANAA0ADQANAA0ADQANAFAAUABQAFAABAAEACsAKwAEAA0ADQAeAFAAKwArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAFAAKwArACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKwArACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwBcAFwADQANAA0AKgBQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAeACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAKwArAFAAKwArAFAAUABQAFAAUABQAFAAUAArAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQAKwAEAAQAKwArAAQABAAEAAQAUAAEAFAABAAEAA0ADQANACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAArACsABAAEAAQABAAEAAQABABQAA4AUAAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAFAABAAEAAQABAAOAB4ADQANAA0ADQAOAB4ABAArACsAKwArACsAKwArACsAUAAEAAQABAAEAAQABAAEAAQABAAEAAQAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAA0ADQANAFAADgAOAA4ADQANACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEACsABAAEAAQABAAEAAQABAAEAFAADQANAA0ADQANACsAKwArACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwAOABMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQACsAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAArACsAKwAEACsABAAEACsABAAEAAQABAAEAAQABABQAAQAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAKwBQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQAKwAEAAQAKwAEAAQABAAEAAQAUAArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAaABoAGgAaAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwArAA0AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsADQANAA0ADQANACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAASABIAEgAQwBDAEMAUABQAFAAUABDAFAAUABQAEgAQwBIAEMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAASABDAEMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwAJAAkACQAJAAkACQAJABYAEQArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABIAEMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwANAA0AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAQABAAEAAQABAANACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAA0ADQANAB4AHgAeAB4AHgAeAFAAUABQAFAADQAeACsAKwArACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAANAA0AHgAeACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwAEAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwArACsAKwAEAAQABAAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAARwBHABUARwAJACsAKwArACsAKwArACsAKwArACsAKwAEAAQAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACsAKwArACsAKwArACsAKwBXAFcAVwBXAFcAVwBXAFcAVwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUQBRAFEAKwArACsAKwArACsAKwArACsAKwArACsAKwBRAFEAUQBRACsAKwArACsAKwArACsAKwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUAArACsAHgAEAAQADQAEAAQABAAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwArAB4AHgAeAB4AHgAeAB4AKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAAQABAAEAAQABAAeAB4AHgAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAB4AHgAEAAQABAAEAAQABAAEAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQAHgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwBQAFAAKwArAFAAKwArAFAAUAArACsAUABQAFAAUAArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAUAArAFAAUABQAFAAUABQAFAAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwBQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAHgAeAFAAUABQAFAAUAArAFAAKwArACsAUABQAFAAUABQAFAAUAArAB4AHgAeAB4AHg
vendor: 4,419 bytes, line 33138
33138AeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAeACsAKwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAeAB4AHgAeAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAeAB4AHgAeAB4AHgAeAB4ABAAeAB4AHgAeAB4AHgAeAB4AHgAeAAQAHgAeAA0ADQANAA0AHgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAEAAQABAAEAAQAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAAQABAAEAAQABAAEAAQAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArAAQABAAEAAQABAAEAAQAKwAEAAQAKwAEAAQABAAEAAQAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwAEAAQABAAEAAQABAAEAFAAUABQAFAAUABQAFAAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwBQAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArABsAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArAB4AHgAeAB4ABAAEAAQABAAEAAQABABQACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArABYAFgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAGgBQAFAAUAAaAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAKwBQACsAKwBQACsAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAKwBQACsAUAArACsAKwArACsAKwBQACsAKwArACsAUAArAFAAKwBQACsAUABQAFAAKwBQAFAAKwBQACsAKwBQACsAUAArAFAAKwBQACsAUAArAFAAUAArAFAAKwArAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUABQAFAAUAArAFAAUABQAFAAKwBQACsAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAUABQAFAAKwBQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8AJQAlACUAHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHgAeAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB4AHgAeACUAJQAlAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAJQAlACUAJQAlACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAB4AHgAlACUAJQAlACUAHgAlACUAJQAlACUAIAAgACAAJQAlACAAJQAlACAAIAAgACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACEAIQAhACEAIQAlACUAIAAgACUAJQAgACAAIAAgACAAIAAgACAAIAAgACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAJQAlACUAIAAlACUAJQAlACAAIAAgACUAIAAgACAAJQAlACUAJQAlACUAJQAgACUAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAHgAlAB4AJQAeACUAJQAlACUAJQAgACUAJQAlACUAHgAlAB4AHgAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAIAAlACUAJQAlACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAJQAlACUAJQAgACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAlACUAJQAlACUAJQAlACAAIAAgACUAJQAlACAAIAAgACAAIAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeABcAFwAXABUAFQAVAB4AHgAeAB4AJQAlACUAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAIAAgACUAJQAlACUAJQAlACUAJQAlACAAJQAlACUAJQAlACUAJQAlACUAJQAlACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAlACUAJQAlACUAJQAlACUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAlACUAJQAlACUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAgACUAJQAgACUAJQAlACUAJQAlACUAJQAgACAAIAAgACAAIAAgACAAJQAlACUAJQAlACUAIAAlACUAJQAlACUAJQAlACUAJQAgACAAIAAgACAAIAAgACAAIAAgACUAJQAgACAAIAAlA
vendor: 50,172 bytes, line 33138
33138CUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAgACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAIAAlACAAIAAlACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAgACAAIAAlACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAJQAlAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAKwArAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwAlACUAJQAlACUAJQAlACUAJQAlACUAVwBXACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAKwAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAA=="),L=Array.isArray(m)?function(A){for(var e=A.length,t=[],r=0;r<e;r+=4)t.push(A[r+3]<<24|A[r+2]<<16|A[r+1]<<8|A[r]);return t}(m):new Uint32Array(m),b=Array.isArray(m)?function(A){for(var e=A.length,t=[],r=0;r<e;r+=2)t.push(A[r+1]<<8|A[r]);return t}(m):new Uint16Array(m),y=w(b,12,L[4]/2),K=2===L[5]?w(b,(24+L[4])/2):(m=L,b=Math.ceil((24+L[4])/4),m.slice?m.slice(b,K):new Uint32Array(Array.prototype.slice.call(m,b,K))),new U(L[0],L[1],L[2],L[3],y,K)),BA=[J,36],nA=[1,2,3,5],sA=[D,8],oA=[P,N],iA=nA.concat(sA),QA=[j,z,$,Z,_],cA=[x,v],aA=(gA.prototype.slice=function(){return g.apply(void 0,this.codePoints.slice(this.start,this.end))},gA);function gA(A,e,t,r){this.codePoints=A,this.required="!"===e,this.start=t,this.end=r}function wA(A,e){var t=Q(A),r=(e=I(t,e))[0],B=e[1],n=e[2],s=t.length,o=0,i=0;return{next:function(){if(s<=i)return{done:!0,value:null};for(var A=tA;i<s&&(A=function(A,e,t,r,B){if(0===t[r])return tA;var n=r-1;if(Array.isArray(B)&&!0===B[n])return tA;var s=n-1,o=1+n,i=e[n],r=0<=s?e[s]:0,B=e[o];if(2===i&&3===B)return tA;if(-1!==nA.indexOf(i))return"!";if(-1!==nA.indexOf(B))return tA;if(-1!==sA.indexOf(B))return tA;if(8===E(n,e))return"÷";if(11===rA.get(A[n]))return tA;if((i===Y||i===W)&&11===rA.get(A[o]))return tA;if(7===i||7===B)return tA;if(9===i)return tA;if(-1===[D,v,x].indexOf(i)&&9===B)return tA;if(-1!==[M,S,T,k,X].indexOf(B))return tA;if(E(n,e)===V)return tA;if(p(23,V,n,e))return tA;if(p([M,S],O,n,e))return tA;if(p(12,12,n,e))return tA;if(i===D)return"÷";if(23===i||23===B)return tA;if(16===B||16===i)return"÷";if(-1!==[v,x,O].indexOf(B)||14===i)return tA;if(36===r&&-1!==cA.indexOf(i))return tA;if(i===X&&36===B)return tA;if(B===G)return tA;if(-1!==BA.indexOf(B)&&i===R||-1!==BA.indexOf(i)&&B===R)return tA;if(i===P&&-1!==[q,Y,W].indexOf(B)||-1!==[q,Y,W].indexOf(i)&&B===N)return tA;if(-1!==BA.indexOf(i)&&-1!==oA.indexOf(B)||-1!==oA.indexOf(i)&&-1!==BA.indexOf(B))return tA;if(-1!==[P,N].indexOf(i)&&(B===R||-1!==[V,x].indexOf(B)&&e[1+o]===R)||-1!==[V,x].indexOf(i)&&B===R||i===R&&-1!==[R,X,k].indexOf(B))return tA;if(-1!==[R,X,k,M,S].indexOf(B))for(var Q=n;0<=Q;){if((c=e[Q])===R)return tA;if(-1===[X,k].indexOf(c))break;Q--}if(-1!==[P,N].indexOf(B))for(var c,Q=-1!==[M,S].indexOf(i)?s:n;0<=Q;){if((c=e[Q])===R)return tA;if(-1===[X,k].indexOf(c))break;Q--}if(j===i&&-1!==[j,z,Z,_].indexOf(B)||-1!==[z,Z].indexOf(i)&&-1!==[z,$].indexOf(B)||-1!==[$,_].indexOf(i)&&B===$)return tA;if(-1!==QA.indexOf(i)&&-1!==[G,N].indexOf(B)||-1!==QA.indexOf(B)&&i===P)return tA;if(-1!==BA.indexOf(i)&&-1!==BA.indexOf(B))return tA;if(i===k&&-1!==BA.indexOf(B))return tA;if(-1!==BA.concat(R).indexOf(i)&&B===V&&-1===eA.indexOf(A[o])||-1!==BA.concat(R).indexOf(B)&&i===S)return tA;if(41===i&&41===B){for(var a=t[n],g=1;0<a&&41===e[--a];)g++;if(g%2!=0)return tA}return i===Y&&B===W?tA:"÷"}(t,B,r,++i,n))===tA;);if(A===tA&&i!==s)return{done:!0,value:null};var e=new aA(t,A,o,i);return o=i,{value:e,done:!1}}}}function UA(A){return 48<=A&&A<=57}function lA(A){return UA(A)||65<=A&&A<=70||97<=A&&A<=102}function CA(A){return 10===A||9===A||32===A}function uA(A){return 97<=(t=e=A)&&t<=122||65<=(e=e)&&e<=90||128<=A||95===A;var e,t}function FA(A){return uA(A)||UA(A)||45===A}function hA(A,e){return 92===A&&10!==e}function dA(A,e,t){return 45===A?uA(e)||hA(e,t):!!uA(A)||92===A&&10!==e}function fA(A,e,t){return 43===A||45===A?!!UA(e)||46===e&&UA(t):UA(46===A?e:A)}var HA={type:2},pA={type:3},EA={type:4},IA={type:13},yA={type:8},KA={type:21},mA={type:9},LA={type:10},bA={type:11},DA={type:12},vA={type:14},xA={type:23},MA={type:1},SA={type:25},TA={type:24},GA={type:26},OA={type:27},VA={type:28},kA={type:29},RA={type:31},NA={type:32},PA=(XA.prototype.write=function(A){this._value=this._value.concat(Q(A))},XA.prototype.read=function(){for(var A=[],e=this.consumeToken();e!==NA;)A.push(e),e=this.consumeToken();return A},XA.prototype.consumeToken=function(){var A=this.consumeCodePoint();switch(A){case 34:return this.consumeStringToken(34);case 35:var e=this.peekCodePoint(0),t=this.peekCodePoint(1),r=this.peekCodePoint(2);if(FA(e)||hA(t,r)){var B=dA(e,t,r)?2:1;return{type:5,value:this.consumeName(),flags:B}}break;case 36:if(61===this.peekCodePoint(0))return this.consumeCodePoint(),IA;break;case 39:return this.consumeStringToken(39);case 40:return HA;case 41:return pA;case 42:if(61===this.peekCodePoint(0))return this.consumeCodePoint(),vA;break;case 43:if(fA(A,this.peekCodePoint(0),this.peekCodePoint(1)))return this.reconsumeCodePoint(A),this.consumeNumericToken();break;case 44:return EA;case 45:var r=A,B=this.peekCodePoint(0),n=this.peekCodePoint(1);if(fA(r,B,n))return this.reconsumeCodePoint(A),this.consumeNumericToken();if(dA(r,B,n))return this.reconsumeCodePoint(A),this.consumeIdentLikeToken();if(45===B&&62===n)return this.consumeCodePoint(),this.consumeCodePoint(),TA;break;case 46:if(fA(A,this.peekCodePoint(0),this.peekCodePoint(1)))return this.reconsumeCodePoint(A),this.consumeNumericToken();break;case 47:if(42===this.peekCodePoint(0))for(this.consumeCodePoint();;){var s=this.consumeCodePoint();if(42===s&&47===(s=this.consumeCodePoint()))return this.consumeToken();if(-1===s)return this.consumeToken()}break;case 58:return GA;case 59:return OA;case 60:if(33===this.peekCodePoint(0)&&45===this.peekCodePoint(1)&&45===this.peekCodePoint(2))return this.consumeCodePoint(),this.consumeCodePoint(),SA;break;case 64:var n=this.peekCodePoint(0),o=this.peekCodePoint(1),i=this.peekCodePoint(2);if(dA(n,o,i))return{type:7,value:this.consumeName()};break;case 91:return VA;case 92:if(hA(A,this.peekCodePoint(0)))return this.reconsumeCodePoint(A),this.consumeIdentLikeToken();break;case 93:return kA;case 61:if(61===this.peekCodePoint(0))return this.consumeCodePoint(),yA;break;case 123:return bA;case 125:return DA;case 117:case 85:o=this.peekCodePoint(0),i=this.peekCodePoint(1);return 43!==o||!lA(i)&&63!==i||(this.consumeCodePoint(),this.consumeUnicodeRangeToken()),this.reconsumeCodePoint(A),this.consumeIdentLikeToken();case 124:if(61===this.peekCodePoint(0))return this.consumeCodePoint(),mA;if(124===this.peekCodePoint(0))return this.consumeCodePoint(),KA;break;case 126:if(61===this.peekCodePoint(0))return this.consumeCodePoint(),LA;break;case-1:return NA}return CA(A)?(this.consumeWhiteSpace(),RA):UA(A)?(this.reconsumeCodePoint(A),this.consumeNumericToken()):uA(A)?(this.reconsumeCodePoint(A),this.consumeIdentLikeToken()):{type:6,value:g(A)}},XA.prototype.consumeCodePoint=function(){var A=this._value.shift();return void 0===A?-1:A},XA.prototype.reconsumeCodePoint=function(A){this._value.unshift(A)},XA.prototype.peekCodePoint=function(A){return A>=this._value.length?-1:this._value[A]},XA.prototype.consumeUnicodeRangeToken=function(){for(var A=[],e=this.consumeCodePoint();lA(e)&&A.length<6;)A.push(e),e=this.consumeCodePoint();for(var t=!1;63===e&&A.length<6;)A.push(e),e=this.consumeCodePoint(),t=!0;if(t)return{type:30,start:parseInt(g.apply(void 0,A.map(function(A){return 63===A?48:A})),16),end:parseInt(g.apply(void 0,A.map(function(A){return 63===A?70:A})),16)};var r=parseInt(g.apply(void 0,A),16);if(45===this.peekCodePoint(0)&&lA(this.peekCodePoint(1))){this.consumeCodePoint();for(var e=this.consumeCodePoint(),B=[];lA(e)&&B.length<6;)B.push(e),e=this.consumeCodePoint();return{type:30,start:r,end:parseInt(g.apply(void 0,B),16)}}return{type:30,start:r,end:r}},XA.prototype.consumeIdentLikeToken=function(){var A=this.consumeName();return"url"===A.toLowerCase()&&40===this.peekCodePoint(0)?(this.consumeCodePoint(),this.consumeUrlToken()):40===this.peekCodePoint(0)?(this.consumeCodePoint(),{type:19,value:A}):{type:20,value:A}},XA.prototype.consumeUrlToken=function(){var A=[];if(this.consumeWhiteSpace(),-1===this.peekCodePoint(0))return{type:22,value:""};var e,t=this.peekCodePoint(0);if(39===t||34===t){t=this.consumeStringToken(this.consumeCodePoint());return 0===t.type&&(this.consumeWhiteSpace(),-1===this.peekCodePoint(0)||41===this.peekCodePoint(0))?(this.consumeCodePoint(),{type:22,value:t.value}):(this.consumeBadUrlRemnants(),xA)}for(;;){var r=this.consumeCodePoint();if(-1===r||41===r)return{type:22,value:g.apply(void 0,A)};if(CA(r))return this.consumeWhiteSpace(),-1===this.peekCodePoint(0)||41===this.peekCodePoint(0)?(this.consumeCodePoint(),{type:22,value:g.apply(void 0,A)}):(this.consumeBadUrlRemnants(),xA);if(34===r||39===r||40===r||(0<=(e=r)&&e<=8||11===e||14<=e&&e<=31||127===e))return this.consumeBadUrlRemnants(),xA;if(92===r){if(!hA(r,this.peekCodePoint(0)))return this.consumeBadUrlRemnants(),xA;A.push(this.consumeEscapedCodePoint())}else A.push(r)}},XA.prototype.consumeWhiteSpace=function(){for(;CA(this.peekCodePoint(0));)this.consumeCodePoint()},XA.prototype.consumeBadUrlRemnants=function(){for(;;){var A=this.consumeCodePoint();if(41===A||-1===A)return;hA(A,this.peekCodePoint(0))&&this.consumeEscapedCodePoint()}},XA.prototype.consumeStringSlice=function(A){for(var e="";0<A;){var t=Math.min(5e4,A);e+=g.apply(void 0,this._value.splice(0,t)),A-=t}return this._value.shift(),e},XA.prototype.consumeStringToken=function(A){for(var e="",t=0;;){var r,B=this._value[t];if(-1===B||void 0===B||B===A)return{type:0,value:e+=this.consumeStringSlice(t)};if(10===B)return this._value.splice(0,t),MA;92!==B||-1!==(r=this._value[t+1])&&void 0!==r&&(10===r?(e+=this.consumeStringSlice(t),t=-1,this._value.shift()):hA(B,r)&&(e+=this.consumeStringSlice(t),e+=g(this.consumeEscapedCodePoint()),t=-1)),t++}},XA.prototype.consumeNumber=function(){var A=[],e=4;for(43!==(t=this.peekCodePoint(0))&&45!==t||A.push(this.consumeCodePoint());UA(this.peekCodePoint(0));)A.push(this.consumeCodePoint());var t=this.peekCodePoint(0),r=this.peekCodePoint(1);if(46===t&&UA(r))for(A.push(this.consumeCodePoint(),this.consumeCodePoint()),e=8;UA(this.peekCodePoint(0));)A.push(this.consumeCodePoint());t=this.peekCodePoint(0);var r=this.peekCodePoint(1),B=this.peekCodePoint(2);if((69===t||101===t)&&((43===r||45===r)&&UA(B)||UA(r)))for(A.push(this.consumeCodePoint(),this.consumeCodePoint()),e=8;UA(this.peekCodePoint(0));)A.push(this.consumeCodePoint());return[function(A){var e=0,t=1;43!==A[e]&&45!==A[e]||(45===A[e]&&(t=-1),e++);for(var r=[];UA(A[e]);)r.push(A[e++]);var B=r.length?parseInt(g.apply(void 0,r),10):0;46===A[e]&&e++;for(var n=[];UA(A[e]);)n.push(A[e++]);var s=n.length,o=s?parseInt(g.apply(void 0,n),10):0;69!==A[e]&&101!==A[e]||e++;var i=1;43!==A[e]&&45!==A[e]||(45===A[e]&&(i=-1),e++);for(var Q=[];UA(A[e]);)Q.push(A[e++]);var c=Q.length?parseInt(g.apply(void 0,Q),10):0;return t*(B+o*Math.pow(10,-s))*Math.pow(10,i*c)}(A),e]},XA.prototype.consumeNumericToken=function(){var A=this.consumeNumber(),e=A[0],t=A[1],r=this.peekCodePoint(0),B=this.peekCodePoint(1),A=this.peekCodePoint(2);return dA(r,B,A)?{type:15,number:e,flags:t,unit:this.consumeName()}:37===r?(this.consumeCodePoint(),{type:16,number:e,flags:t}):{type:17,number:e,flags:t}},XA.prototype.consumeEscapedCodePoint=function(){var A,e=this.consumeCodePoint();if(lA(e)){for(var t=g(e);lA(this.peekCodePoint(0))&&t.length<6;)t+=g(this.consumeCodePoint());CA(this.peekCodePoint(0))&&this.consumeCodePoint();var r=parseInt(t,16);return 0===r||55296<=(A=r)&&A<=57343||1114111<r?65533:r}return-1===e?65533:e},XA.prototype.consumeName=function(){for(var A="";;){var e=this.consumeCodePoint();if(FA(e))A+=g(e);else{if(!hA(e,this.peekCodePoint(0)))return this.reconsumeCodePoint(e),A;A+=g(this.consumeEscapedCodePoint())}}},XA);function XA(){this._value=[]}var JA=(YA.create=function(A){var e=new PA;return e.write(A),new YA(e.read())},YA.parseValue=function(A){return YA.create(A).parseComponentValue()},YA.parseValues=function(A){return YA.create(A).parseComponentValues()},YA.prototype.parseComponentValue=function(){for(var A=this.consumeToken();31===A.type;)A=this.consumeToken();if(32===A.type)throw new SyntaxError("Error parsing CSS component value, unexpected EOF");this.reconsumeToken(A);for(var e=this.consumeComponentValue();31===(A=this.consumeToken()).type;);if(32===A.type)return e;throw new SyntaxError("Error parsing CSS component value, multiple values found when expecting only one")},YA.prototype.parseComponentValues=function(){for(var A=[];;){var e=this.consumeComponentValue();if(32===e.type)return A;A.push(e),A.push()}},YA.prototype.consumeComponentValue=function(){var A=this.consumeToken();switch(A.type){case 11:case 28:case 2:return this.consumeSimpleBlock(A.type);case 19:return this.consumeFunction(A)}return A},YA.prototype.consumeSimpleBlock=function(A){for(var e={type:A,values:[]},t=this.consumeToken();;){if(32===t.type||ce(t,A))return e;this.reconsumeToken(t),e.values.push(this.consumeComponentValue()),t=this.consumeToken()}},YA.prototype.consumeFunction=function(A){for(var e={name:A.value,values:[],type:18};;){var t=this.consumeToken();if(32===t.type||3===t.type)return e;this.reconsumeToken(t),e.values.push(this.consumeComponentValue())}},YA.prototype.consumeToken=function(){var A=this._tokens.shift();return void 0===A?NA:A},YA.prototype.reconsumeToken=function(A){this._tokens.unshift(A)},YA);function YA(A){this._tokens=A}function WA(A){return 15===A.type}function ZA(A){return 17===A.type}function _A(A){return 20===A.type}function qA(A){return 0===A.type}function jA(A,e){return _A(A)&&A.value===e}function zA(A){return 31!==A.type}function $A(A){return 31!==A.type&&4!==A.type}function Ae(A){var e=[],t=[];return A.forEach(function(A){if(4===A.type){if(0===t.length)throw new Error("Error parsing function args, zero tokens for arg");return e.push(t),void(t=[])}31!==A.type&&t.push(A)}),t.length&&e.push(t),e}function ee(A){return 17===A.type||15===A.type}function te(A){return 16===A.type||ee(A)}function re(A){return 1<A.length?[A[0],A[1]]:[A[0]]}function Be(A,e,t){var r=A[0],A=A[1];return[Ue(r,e),Ue(void 0!==A?A:r,t)]}function ne(A){return 15===A.type&&("deg"===A.unit||"grad"===A.unit||"rad"===A.unit||"turn"===A.unit)}function se(A){switch(A.filter(_A).map(function(A){return A.value}).join(" ")){case"to bottom right":case"to right bottom":case"left top":case"top left":return[ae,ae];case"to top":case"bottom":return Ce(0);case"to bottom left":case"to left bottom":case"right top":case"top right":return[ae,we];case"to right":case"left":return Ce(90);case"to top left":case"to left top":case"right bottom":case"bottom right":return[we,we];case"to bottom":case"top":return Ce(180);case"to top right":case"to right top":case"left bottom":case"bottom left":return[we,ae];case"to left":case"right":return Ce(270)}return 0}function oe(A){return 0==(255&A)}function ie(A){var e=255&A,t=255&A>>8,r=255&A>>16,A=255&A>>24;return e<255?"rgba("+A+","+r+","+t+","+e/255+")":"rgb("+A+","+r+","+t+")"}function Qe(A,e){if(17===A.type)return A.number;if(16!==A.type)return 0;var t=3===e?1:255;return 3===e?A.number/100*t:Math.round(A.number/100*t)}var ce=function(A,e){return 11===e&&12===A.type||(28===e&&29===A.type||2===e&&3===A.type)},ae={type:17,number:0,flags:4},ge={type:16,number:50,flags:4},we={type:16,number:100,flags:4},Ue=function(A,e){if(16===A.type)return A.number/100*e;if(WA(A))switch(A.unit){case"rem":case"em":return 16*A.number;default:return A.number}return A.number},le=function(A,e){if(15===e.type)switch(e.unit){case"deg":return Math.PI*e.number/180;case"grad":return Math.PI/200*e.number;case"rad":return e.number;case"turn":return 2*Math.PI*e.number}throw new Error("Unsupported angle type")},Ce=function(A){return Math.PI*A/180},ue=function(A,e){if(18===e.type){var t=me[e.name];if(void 0===t)throw new Error('Attempting to parse an unsupported color function "'+e.name+'"');return t(A,e.values)}if(5===e.type){if(3===e.value.length){var r=e.value.substring(0,1),B=e.value.substring(1,2),n=e.value.substring(2,3);return Fe(parseInt(r+r,16),parseInt(B+B,16),parseInt(n+n,16),1)}if(4===e.value.length){var r=e.value.substring(0,1),B=e.value.substring(1,2),n=e.value.substring(2,3),s=e.value.substring(3,4);return Fe(parseInt(r+r,16),parseInt(B+B,16),parseInt(n+n,16),parseInt(s+s,16)/255)}if(6===e.value.length){r=e.value.substring(0,2),B=e.value.substring(2,4),n=e.value.substring(4,6);return Fe(parseInt(r,16),parseInt(B,16),parseInt(n,16),1)}if(8===e.value.length){r=e.value.substring(0,2),B=e.value.substring(2,4),n=e.value.substring(4,6),s=e.value.substring(6,8);return Fe(parseInt(r,16),parseInt(B,16),parseInt(n,16),parseInt(s,16)/255)}}if(20===e.type){e=Le[e.value.toUpperCase()];if(void 0!==e)return e}return Le.TRANSPARENT},Fe=function(A,e,t,r){return(A<<24|e<<16|t<<8|Math.round(255*r)<<0)>>>0},he=function(A,e){e=e.filter($A);if(3===e.length){var t=e.map(Qe),r=t[0],B=t[1],t=t[2];return Fe(r,B,t,1)}if(4!==e.length)return 0;e=e.map(Qe),r=e[0],B=e[1],t=e[2],e=e[3];return Fe(r,B,t,e)};function de(A,e,t){return t<0&&(t+=1),1<=t&&--t,t<1/6?(e-A)*t*6+A:t<.5?e:t<2/3?6*(e-A)*(2/3-t)+A:A}function fe(A,e){return ue(A,JA.create(e).parseComponentValue())}function He(A,e){return A=ue(A,e[0]),(e=e[1])&&te(e)?{color:A,stop:e}:{color:A,stop:null}}function pe(A,t){var e=A[0],r=A[A.length-1];null===e.stop&&(e.stop=ae),null===r.stop&&(r.stop=we);for(var B=[],n=0,s=0;s<A.length;s++){var o=A[s].stop;null!==o?(n<(o=Ue(o,t))?B.push(o):B.push(n),n=o):B.push(null)}for(var i=null,s=0;s<B.length;s++){var Q=B[s];if(null===Q)null===i&&(i=s);else if(null!==i){for(var c=s-i,a=(Q-B[i-1])/(1+c),g=1;g<=c;g++)B[i+g-1]=a*g;i=null}}return A.map(function(A,e){return{color:A.color,stop:Math.max(Math.min(1,B[e]/t),0)}})}function Ee(A,e,t){var r="number"==typeof A?A:(s=e/2,r=(n=t)/2,s=Ue((B=A)[0],e)-s,n=r-Ue(B[1],n),(Math.atan2(n,s)+2*Math.PI)%(2*Math.PI)),B=Math.abs(e*Math.sin(r))+Math.abs(t*Math.cos(r)),n=e/2,s=t/2,e=B/2,t=Math.sin(r-Math.PI/2)*e,e=Math.cos(r-Math.PI/2)*e;return[B,n-e,n+e,s-t,s+t]}function Ie(A,e){return Math.sqrt(A*A+e*e)}function ye(A,e,B,n,s){return[[0,0],[0,e],[A,0],[A,e]].reduce(function(A,e){var t=e[0],r=e[1],r=Ie(B-t,n-r);return(s?r<A.optimumDistance:r>A.optimumDistance)?{optimumCorner:e,optimumDistance:r}:A},{optimumDistance:s?1/0:-1/0,optimumCorner:null}).optimumCorner}var Ke=function(A,e){var t=e.filter($A),r=t[0],B=t[1],n=t[2],e=t[3],t=(17===r.type?Ce(r.number):le(A,r))/(2*Math.PI),A=te(B)?B.number/100:0,r=te(n)?n.number/100:0,B=void 0!==e&&te(e)?Ue(e,1):1;if(0==A)return Fe(255*r,255*r,255*r,1);n=r<=.5?r*(1+A):r+A-r*A,e=2*r-n,A=de(e,n,t+1/3),r=de(e,n,t),t=de(e,n,t-1/3);return Fe(255*A,255*r,255*t,B)},me={hsl:Ke,hsla:Ke,rgb:he,rgba:he},Le={ALICEBLUE:4042850303,ANTIQUEWHITE:4209760255,AQUA:16777215,AQUAMARINE:2147472639,AZURE:4043309055,BEIGE:4126530815,BISQUE:4293182719,BLACK:255,BLANCHEDALMOND:4293643775,BLUE:65535,BLUEVIOLET:2318131967,BROWN:2771004159,BURLYWOOD:3736635391,CADETBLUE:1604231423,CHARTREUSE:2147418367,CHOCOLATE:3530104575,CORAL:4286533887,CORNFLOWERBLUE:1687547391,CORNSILK:4294499583,CRIMSON:3692313855,CYAN:16777215,DARKBLUE:35839,DARKCYAN:9145343,DARKGOLDENROD:3095837695,DARKGRAY:2846468607,DARKGREEN:6553855,DARKGREY:2846468607,DARKKHAKI:3182914559,DARKMAGENTA:2332068863,DARKOLIVEGREEN:1433087999,DARKORANGE:4287365375,DARKORCHID:2570243327,DARKRED:2332033279,DARKSALMON:3918953215,DARKSEAGREEN:2411499519,DARKSLATEBLUE:1211993087,DARKSLATEGRAY:793726975,DARKSLATEGREY:793726975,DARKTURQUOISE:13554175,DARKVIOLET:2483082239,DEEPPINK:4279538687,DEEPSKYBLUE:12582911,DIMGRAY:1768516095,DIMGREY:1768516095,DODGERBLUE:512819199,FIREBRICK:2988581631,FLORALWHITE:4294635775,FORESTGREEN:579543807,FUCHSIA:4278255615,GAINSBORO:3705462015,GHOSTWHITE:4177068031,GOLD:4292280575,GOLDENROD:3668254975,GRAY:2155905279,GREEN:8388863,GREENYELLOW:2919182335,GREY:2155905279,HONEYDEW:4043305215,HOTPINK:4285117695,INDIANRED:3445382399,INDIGO:1258324735,IVORY:4294963455,KHAKI:4041641215,LAVENDER:3873897215,LAVENDERBLUSH:4293981695,LAWNGREEN:2096890111,LEMONCHIFFON:4294626815,LIGHTBLUE:2916673279,LIGHTCORAL:4034953471,LIGHTCYAN:3774873599,LIGHTGOLDENRODYELLOW:4210742015,LIGHTGRAY:3553874943,LIGHTGREEN:2431553791,LIGHTGREY:3553874943,LIGHTPINK:4290167295,LIGHTSALMON:4288707327,LIGHTSEAGREEN:548580095,LIGHTSKYBLUE:2278488831,LIGHTSLATEGRAY:2005441023,LIGHTSLATEGREY:2005441023,LIGHTSTEELBLUE:2965692159,LIGHTYELLOW:4294959359,LIME:16711935,LIMEGREEN:852308735,LINEN:4210091775,MAGENTA:4278255615,MAROON:2147483903,MEDIUMAQUAMARINE:1724754687,MEDIUMBLUE:52735,MEDIUMORCHID:3126187007,MEDIUMPURPLE:2473647103,MEDIUMSEAGREEN:1018393087,MEDIUMSLATEBLUE:2070474495,MEDIUMSPRINGGREEN:16423679,MEDIUMTURQUOISE:1221709055,MEDIUMVIOLETRED:3340076543,MIDNIGHTBLUE:421097727,MINTCREAM:4127193855,MISTYROSE:4293190143,MOCCASIN:4293178879,NAVAJOWHITE:4292783615,NAVY:33023,OLDLACE:4260751103,OLIVE:2155872511,OLIVEDRAB:1804477439,ORANGE:4289003775,ORANGERED:4282712319,ORCHID:3664828159,PALEGOLDENROD:4008225535,PALEGREEN:2566625535,PALETURQUOISE:2951671551,PALEVIOLETRED:3681588223,PAPAYAWHIP:4293907967,PEACHPUFF:4292524543,PERU:3448061951,PINK:4290825215,PLUM:3718307327,POWDERBLUE:2967529215,PURPLE:2147516671,REBECCAPURPLE:1714657791,RED:4278190335,ROSYBROWN:3163525119,ROYALBLUE:1097458175,SADDLEBROWN:2336560127,SALMON:4202722047,SANDYBROWN:4104413439,SEAGREEN:780883967,SEASHELL:4294307583,SIENNA:2689740287,SILVER:3233857791,SKYBLUE:2278484991,SLATEBLUE:1784335871,SLATEGRAY:1887473919,SLATEGREY:1887473919,SNOW:4294638335,SPRINGGREEN:16744447,STEELBLUE:1182971135,TAN:3535047935,TEAL:8421631,THISTLE:3636451583,TOMATO:4284696575,TRANSPARENT:0,TURQUOISE:1088475391,VIOLET:4001558271,WHEAT:4125012991,WHITE:4294967295,WHITESMOKE:4126537215,YELLOW:4294902015,YELLOWGREEN:2597139199},be={name:"background-clip",initialValue:"border-box",prefix:!1,type:1,parse:function(A,e){return e.map(function(A){if(_A(A))switch(A.value){case"padding-box":return 1;case"content-box":return 2}return 0})}},De={name:"background-color",initialValue:"transparent",prefix:!1,type:3,format:"color"},Ke=function(t,A){var r=Ce(180),B=[];return Ae(A).forEach(function(A,e){if(0===e){e=A[0];if(20===e.type&&-1!==["top","left","right","bottom"].indexOf(e.value))return void(r=se(A));if(ne(e))return void(r=(le(t,e)+Ce(270))%Ce(360))}A=He(t,A);B.push(A)}),{angle:r,stops:B,type:1}},ve="closest-side",xe="farthest-side",Me="closest-corner",Se="farthest-corner",Te="ellipse",Ge="contain",he=function(r,A){var B=0,n=3,s=[],o=[];return Ae(A).forEach(function(A,e){var t=!0;0===e?t=A.reduce(function(A,e){if(_A(e))switch(e.value){case"center":return o.push(ge),!1;case"top":case"left":return o.push(ae),!1;case"right":case"bottom":return o.push(we),!1}else if(te(e)||ee(e))return o.push(e),!1;return A},t):1===e&&(t=A.reduce(function(A,e){if(_A(e))switch(e.value){case"circle":return B=0,!1;case Te:return!(B=1);case Ge:case ve:return n=0,!1;case xe:return!(n=1);case Me:return!(n=2);case"cover":case Se:return!(n=3)}else if(ee(e)||te(e))return(n=!Array.isArray(n)?[]:n).push(e),!1;return A},t)),t&&(A=He(r,A),s.push(A))}),{size:n,shape:B,stops:s,position:o,type:2}},Oe=function(A,e){if(22===e.type){var t={url:e.value,type:0};return A.cache.addImage(e.value),t}if(18!==e.type)throw new Error("Unsupported image type "+e.type);t=ke[e.name];if(void 0===t)throw new Error('Attempting to parse an unsupported image function "'+e.name+'"');return t(A,e.values)};var Ve,ke={"linear-gradient":function(t,A){var r=Ce(180),B=[];return Ae(A).forEach(function(A,e){if(0===e){e=A[0];if(20===e.type&&"to"===e.value)return void(r=se(A));if(ne(e))return void(r=le(t,e))}A=He(t,A);B.push(A)}),{angle:r,stops:B,type:1}},"-moz-linear-gradient":Ke,"-ms-linear-gradient":Ke,"-o-linear-gradient":Ke,"-webkit-linear-gradient":Ke,"radial-gradient":function(B,A){var n=0,s=3,o=[],i=[];return Ae(A).forEach(function(A,e){var t,r=!0;0===e&&(t=!1,r=A.reduce(function(A,e){if(t)if(_A(e))switch(e.value){case"center":return i.push(ge),A;case"top":case"left":return i.push(ae),A;case"right":case"bottom":return i.push(we),A}else(te(e)||ee(e))&&i.push(e);else if(_A(e))switch(e.value){case"circle":return n=0,!1;case Te:return!(n=1);case"at":return!(t=!0);case ve:return s=0,!1;case"cover":case xe:return!(s=1);case Ge:case Me:return!(s=2);case Se:return!(s=3)}else if(ee(e)||te(e))return(s=!Array.isArray(s)?[]:s).push(e),!1;return A},r)),r&&(A=He(B,A),o.push(A))}),{size:s,shape:n,stops:o,position:i,type:2}},"-moz-radial-gradient":he,"-ms-radial-gradient":he,"-o-radial-gradient":he,"-webkit-radial-gradient":he,"-webkit-gradient":function(r,A){var e=Ce(180),B=[],n=1;return Ae(A).forEach(function(A,e){var t,A=A[0];if(0===e){if(_A(A)&&"linear"===A.value)return void(n=1);if(_A(A)&&"radial"===A.value)return void(n=2)}18===A.type&&("from"===A.name?(t=ue(r,A.values[0]),B.push({stop:ae,color:t})):"to"===A.name?(t=ue(r,A.values[0]),B.push({stop:we,color:t})):"color-stop"!==A.name||2===(A=A.values.filter($A)).length&&(t=ue(r,A[1]),A=A[0],ZA(A)&&B.push({stop:{type:16,number:100*A.number,flags:A.flags},color:t})))}),1===n?{angle:(e+Ce(180))%Ce(360),stops:B,type:n}:{size:3,shape:0,stops:B,position:[],type:n}}},Re={name:"background-image",initialValue:"none",type:1,prefix:!1,parse:function(e,A){if(0===A.length)return[];var t=A[0];return 20===t.type&&"none"===t.value?[]:A.filter(function(A){return $A(A)&&!(20===(A=A).type&&"none"===A.value||18===A.type&&!ke[A.name])}).map(function(A){return Oe(e,A)})}},Ne={name:"background-origin",initialValue:"border-box",prefix:!1,type:1,parse:function(A,e){return e.map(function(A){if(_A(A))switch(A.value){case"padding-box":return 1;case"content-box":return 2}return 0})}},Pe={name:"background-position",initialValue:"0% 0%",type:1,prefix:!1,parse:function(A,e){return Ae(e).map(function(A){return A.filter(te)}).map(re)}},Xe={name:"background-repeat",initialValue:"repeat",prefix:!1,type:1,parse:function(A,e){return Ae(e).map(function(A){return A.filter(_A).map(function(A){return A.value}).join(" ")}).map(Je)}},Je=function(A){switch(A){case"no-repeat":return 1;case"repeat-x":case"repeat no-repeat":return 2;case"repeat-y":case"no-repeat repeat":return 3;default:return 0}};(he=Ve=Ve||{}).AUTO="auto",he.CONTAIN="contain";function Ye(A,e){return _A(A)&&"normal"===A.value?1.2*e:17===A.type?e*A.number:te(A)?Ue(A,e):e}var We,Ze,_e={name:"background-size",initialValue:"0",prefix:!(he.COVER="cover"),type:1,parse:function(A,e){return Ae(e).map(function(A){return A.filter(qe)})}},qe=function(A){return _A(A)||te(A)},he=function(A){return{name:"border-"+A+"-color",initialValue:"transparent",prefix:!1,type:3,format:"color"}},je=he("top"),ze=he("right"),$e=he("bottom"),At=he("left"),he=function(A){return{name:"border-radius-"+A,initialValue:"0 0",prefix:!1,type:1,parse:function(A,e){return re(e.filter(te))}}},et=he("top-left"),tt=he("top-right"),rt=he("bottom-right"),Bt=he("bottom-left"),he=function(A){return{name:"border-"+A+"-style",initialValue:"solid",prefix:!1,type:2,parse:function(A,e){switch(e){case"none":return 0;case"dashed":return 2;case"dotted":return 3;case"double":return 4}return 1}}},nt=he("top"),st=he("right"),ot=he("bottom"),it=he("left"),he=function(A){return{name:"border-"+A+"-width",initialValue:"0",type:0,prefix:!1,parse:function(A,e){return WA(e)?e.number:0}}},Qt=he("top"),ct=he("right"),at=he("bottom"),gt=he("left"),wt={name:"color",initialValue:"transparent",prefix:!1,type:3,format:"color"},Ut={name:"direction",initialValue:"ltr",prefix:!1,type:2,parse:function(A,e){return"rtl"!==e?0:1}},lt={name:"display",initialValue:"inline-block",prefix:!1,type:1,parse:function(A,e){return e.filter(_A).reduce(function(A,e){return A|Ct(e.value)},0)}},Ct=function(A){switch(A){case"block":case"-webkit-box":return 2;case"inline":return 4;case"run-in":return 8;case"flow":return 16;case"flow-root":return 32;case"table":return 64;case"flex":case"-webkit-flex":return 128;case"grid":case"-ms-grid":return 256;case"ruby":return 512;case"subgrid":return 1024;case"list-item":return 2048;case"table-row-group":return 4096;case"table-header-group":return 8192;case"table-footer-group":return 16384;case"table-row":return 32768;case"table-cell":return 65536;case"table-column-group":return 131072;case"table-column":return 262144;case"table-caption":return 524288;case"ruby-base":return 1048576;case"ruby-text":return 2097152;case"ruby-base-container":return 4194304;case"ruby-text-container":return 8388608;case"contents":return 16777216;case"inline-block":return 33554432;case"inline-list-item":return 67108864;case"inline-table":return 134217728;case"inline-flex":return 268435456;case"inline-grid":return 536870912}return 0},ut={name:"float",initialValue:"none",prefix:!1,type:2,parse:function(A,e){switch(e){case"left":return 1;case"right":return 2;case"inline-start":return 3;case"inline-end":return 4}return 0}},Ft={name:"letter-spacing",initialValue:"0",prefix:!1,type:0,parse:function(A,e){return!(20===e.type&&"normal"===e.value||17!==e.type&&15!==e.type)?e.number:0}},ht={name:"line-break",initialValue:(he=We=We||{}).NORMAL="normal",prefix:!(he.STRICT="strict"),type:2,parse:function(A,e){return"strict"!==e?We.NORMAL:We.STRICT}},dt={name:"line-height",initialValue:"normal",prefix:!1,type:4},ft={name:"list-style-image",initialValue:"none",type:0,prefix:!1,parse:function(A,e){return 20===e.type&&"none"===e.value?null:Oe(A,e)}},Ht={name:"list-style-position",initialValue:"outside",prefix:!1,type:2,parse:function(A,e){return"inside"!==e?1:0}},pt={name:"list-style-type",initialValue:"none",prefix:!1,type:2,parse:function(A,e){switch(e){case"disc":return 0;case"circle":return 1;case"square":return 2;case"decimal":return 3;case"cjk-decimal":return 4;case"decimal-leading-zero":return 5;case"lower-roman":return 6;case"upper-roman":return 7;case"lower-greek":return 8;case"lower-alpha":return 9;case"upper-alpha":return 10;case"arabic-indic":return 11;case"armenian":return 12;case"bengali":return 13;case"cambodian":return 14;case"cjk-earthly-branch":return 15;case"cjk-heavenly-stem":return 16;case"cjk-ideographic":return 17;case"devanagari":return 18;case"ethiopic-numeric":return 19;case"georgian":return 20;case"gujarati":return 21;case"gurmukhi":case"hebrew":return 22;case"hiragana":return 23;case"hiragana-iroha":return 24;case"japanese-formal":return 25;case"japanese-informal":return 26;case"kannada":return 27;case"katakana":return 28;case"katakana-iroha":return 29;case"khmer":return 30;case"korean-hangul-formal":return 31;case"korean-hanja-formal":return 32;case"korean-hanja-informal":return 33;case"lao":return 34;case"lower-armenian":return 35;case"malayalam":return 36;case"mongolian":return 37;case"myanmar":return 38;case"oriya":return 39;case"persian":return 40;case"simp-chinese-formal":return 41;case"simp-chinese-informal":return 42;case"tamil":return 43;case"telugu":return 44;case"thai":return 45;case"tibetan":return 46;case"trad-chinese-formal":return 47;case"trad-chinese-informal":return 48;case"upper-armenian":return 49;case"disclosure-open":return 50;case"disclosure-closed":return 51;default:return-1}}},he=function(A){return{name:"margin-"+A,initialValue:"0",prefix:!1,type:4}},Et=he("top"),It=he("right"),yt=he("bottom"),Kt=he("left"),mt={name:"overflow",initialValue:"visible",prefix:!1,type:1,parse:function(A,e){return e.filter(_A).map(function(A){switch(A.value){case"hidden":return 1;case"scroll":return 2;case"clip":return 3;case"auto":return 4;default:return 0}})}},Lt={name:"overflow-wrap",initialValue:"normal",prefix:!1,type:2,parse:function(A,e){return"break-word"!==e?"normal":"break-word"}},he=function(A){return{name:"padding-"+A,initialValue:"0",prefix:!1,type:3,format:"length-percentage"}},bt=he("top"),Dt=he("right"),vt=he("bottom"),xt=he("left"),Mt={name:"text-align",initialValue:"left",prefix:!1,type:2,parse:function(A,e){switch(e){case"right":return 2;case"center":case"justify":return 1;default:return 0}}},St={name:"position",initialValue:"static",prefix:!1,type:2,parse:function(A,e){switch(e){case"relative":return 1;case"absolute":return 2;case"fixed":return 3;case"sticky":return 4}return 0}},Tt={name:"text-shadow",initialValue:"none",type:1,prefix:!1,parse:function(n,A){return 1===A.length&&jA(A[0],"none")?[]:Ae(A).map(function(A){for(var e={color:Le.TRANSPARENT,offsetX:ae,offsetY:ae,blur:ae},t=0,r=0;r<A.length;r++){var B=A[r];ee(B)?(0===t?e.offsetX=B:1===t?e.offsetY=B:e.blur=B,t++):e.color=ue(n,B)}return e})}},Gt={name:"text-transform",initialValue:"none",prefix:!1,type:2,parse:function(A,e){switch(e){case"uppercase":return 2;case"lowercase":return 1;case"capitalize":return 3}return 0}},Ot={name:"transform",initialValue:"none",prefix:!0,type:0,parse:function(A,e){if(20===e.type&&"none"===e.value)return null;if(18!==e.type)return null;var t=Vt[e.name];if(void 0===t)throw new Error('Attempting to parse an unsupported transform function "'+e.name+'"');return t(e.values)}},Vt={matrix:function(A){A=A.filter(function(A){return 17===A.type}).map(function(A){return A.number});return 6===A.length?A:null},matrix3d:function(A){var e=A.filter(function(A){return 17===A.type}).map(function(A){return A.number}),t=e[0],r=e[1];e[2],e[3];var B=e[4],n=e[5];e[6],e[7],e[8],e[9],e[10],e[11];var s=e[12],A=e[13];return e[14],e[15],16===e.length?[t,r,B,n,s,A]:null}},he={type:16,number:50,flags:4},kt=[he,he],Rt={name:"transform-origin",initialValue:"50% 50%",prefix:!0,type:1,parse:function(A,e){e=e.filter(te);return 2!==e.length?kt:[e[0],e[1]]}},Nt={name:"visible",initialValue:"none",prefix:!1,type:2,parse:function(A,e){switch(e){case"hidden":return 1;case"collapse":return 2;default:return 0}}};(he=Ze=Ze||{}).NORMAL="normal",he.BREAK_ALL="break-all";function Pt(A,e){return 0!=(A&e)}function Xt(A,e,t){return(A=A&&A[Math.min(e,A.length-1)])?t?A.open:A.close:""}var Jt={name:"word-break",initialValue:"normal",prefix:!(he.KEEP_ALL="keep-all"),type:2,parse:function(A,e){switch(e){case"break-all":return Ze.BREAK_ALL;case"keep-all":return Ze.KEEP_ALL;default:return Ze.NORMAL}}},Yt={name:"z-index",initialValue:"auto",prefix:!1,type:0,parse:function(A,e){if(20===e.type)return{auto:!0,order:0};if(ZA(e))return{auto:!1,order:e.number};throw new Error("Invalid z-index number parsed")}},Wt=function(A,e){if(15===e.type)switch(e.unit.toLowerCase()){case"s":return 1e3*e.number;case"ms":return e.number}throw new Error("Unsupported time type")},Zt={name:"opacity",initialValue:"1",type:0,prefix:!1,parse:function(A,e){return ZA(e)?e.number:1}},_t={name:"text-decoration-color",initialValue:"transparent",prefix:!1,type:3,format:"color"},qt={name:"text-decoration-line",initialValue:"none",prefix:!1,type:1,parse:function(A,e){return e.filter(_A).map(function(A){switch(A.value){case"underline":return 1;case"overline":return 2;case"line-through":return 3;case"none":return 4}return 0}).filter(function(A){return 0!==A})}},jt={name:"font-family",initialValue:"",prefix:!1,type:1,parse:function(A,e){var t=[],r=[];return e.forEach(function(A){switch(A.type){case 20:case 0:t.push(A.value);break;case 17:t.push(A.number.toString());break;case 4:r.push(t.join(" ")),t.length=0}}),t.length&&r.push(t.join(" ")),r.map(function(A){return-1===A.indexOf(" ")?A:"'"+A+"'"})}},zt={name:"font-size",initialValue:"0",prefix:!1,type:3,format:"length"},$t={name:"font-weight",initialValue:"normal",type:0,prefix:!1,parse:function(A,e){return ZA(e)?e.number:!_A(e)||"bold"!==e.value?400:700}},Ar={name:"font-variant",initialValue:"none",type:1,prefix:!1,parse:function(A,e){return e.filter(_A).map(function(A){return A.value})}},er={name:"font-style",initialValue:"normal",prefix:!1,type:2,parse:function(A,e){switch(e){case"oblique":return"oblique";case"italic":return"italic";default:return"normal"}}},tr={name:"content",initialValue:"none",type:1,prefix:!1,parse:function(A,e){if(0===e.length)return[];var t=e[0];return 20===t.type&&"none"===t.value?[]:e}},rr={name:"counter-increment",initialValue:"none",prefix:!0,type:1,parse:function(A,e){if(0===e.length)return null;var t=e[0];if(20===t.type&&"none"===t.value)return null;for(var r=[],B=e.filter(zA),n=0;n<B.length;n++){var s=B[n],o=B[n+1];20===s.type&&(o=o&&ZA(o)?o.number:1,r.push({counter:s.value,increment:o}))}return r}},Br={name:"counter-reset",initialValue:"none",prefix:!0,type:1,parse:function(A,e){if(0===e.length)return[];for(var t=[],r=e.filter(zA),B=0;B<r.length;B++){var n=r[B],s=r[B+1];_A(n)&&"none"!==n.value&&(s=s&&ZA(s)?s.number:0,t.push({counter:n.value,reset:s}))}return t}},nr={name:"duration",initialValue:"0s",prefix:!1,type:1,parse:function(e,A){return A.filter(WA).map(function(A){return Wt(e,A)})}},sr={name:"quotes",initialValue:"none",prefix:!0,type:1,parse:function(A,e){if(0===e.length)return null;var t=e[0];if(20===t.type&&"none"===t.value)return null;var r=[],B=e.filter(qA);if(B.length%2!=0)return null;for(var n=0;n<B.length;n+=2){var s=B[n].value,o=B[n+1].value;r.push({open:s,close:o})}return r}},or={name:"box-shadow",initialValue:"none",type:1,prefix:!1,parse:function(n,A){return 1===A.length&&jA(A[0],"none")?[]:Ae(A).map(function(A){for(var e={color:255,offsetX:ae,offsetY:ae,blur:ae,spread:ae,inset:!1},t=0,r=0;r<A.length;r++){var B=A[r];jA(B,"inset")?e.inset=!0:ee(B)?(0===t?e.offsetX=B:1===t?e.offsetY=B:2===t?e.blur=B:e.spread=B,t++):e.color=ue(n,B)}return e})}},ir={name:"paint-order",initialValue:"normal",prefix:!1,type:1,parse:function(A,e){var t=[];return e.filter(_A).forEach(function(A){switch(A.value){case"stroke":t.push(1);break;case"fill":t.push(0);break;case"markers":t.push(2)}}),[0,1,2].forEach(function(A){-1===t.indexOf(A)&&t.push(A)}),t}},Qr={name:"-webkit-text-stroke-color",initialValue:"currentcolor",prefix:!1,type:3,format:"color"},cr={name:"-webkit-text-stroke-width",initialValue:"0",type:0,prefix:!1,parse:function(A,e){return WA(e)?e.number:0}},ar=(gr.prototype.isVisible=function(){return 0<this.display&&0<this.opacity&&0===this.visibility},gr.prototype.isTransparent=function(){return oe(this.backgroundColor)},gr.prototype.isTransformed=function(){return null!==this.transform},gr.prototype.isPositioned=function(){return 0!==this.position},gr.prototype.isPositionedWithZIndex=function(){return this.isPositioned()&&!this.zIndex.auto},gr.prototype.isFloating=function(){return 0!==this.float},gr.prototype.isInlineLevel=function(){return Pt(this.display,4)||Pt(this.display,33554432)||Pt(this.display,268435456)||Pt(this.display,536870912)||Pt(this.display,67108864)||Pt(this.display,134217728)},gr);function gr(A,e){this.animationDuration=lr(A,nr,e.animationDuration),this.backgroundClip=lr(A,be,e.backgroundClip),this.backgroundColor=lr(A,De,e.backgroundColor),this.backgroundImage=lr(A,Re,e.backgroundImage),this.backgroundOrigin=lr(A,Ne,e.backgroundOrigin),this.backgroundPosition=lr(A,Pe,e.backgroundPosition),this.backgroundRepeat=lr(A,Xe,e.backgroundRepeat),this.backgroundSize=lr(A,_e,e.backgroundSize),this.borderTopColor=lr(A,je,e.borderTopColor),this.borderRightColor=lr(A,ze,e.borderRightColor),this.borderBottomColor=lr(A,$e,e.borderBottomColor),this.borderLeftColor=lr(A,At,e.borderLeftColor),this.borderTopLeftRadius=lr(A,et,e.borderTopLeftRadius),this.borderTopRightRadius=lr(A,tt,e.borderTopRightRadius),this.borderBottomRightRadius=lr(A,rt,e.borderBottomRightRadius),this.borderBottomLeftRadius=lr(A,Bt,e.borderBottomLeftRadius),this.borderTopStyle=lr(A,nt,e.borderTopStyle),this.borderRightStyle=lr(A,st,e.borderRightStyle),this.borderBottomStyle=lr(A,ot,e.borderBottomStyle),this.borderLeftStyle=lr(A,it,e.borderLeftStyle),this.borderTopWidth=lr(A,Qt,e.borderTopWidth),this.borderRightWidth=lr(A,ct,e.borderRightWidth),this.borderBottomWidth=lr(A,at,e.borderBottomWidth),this.borderLeftWidth=lr(A,gt,e.borderLeftWidth),this.boxShadow=lr(A,or,e.boxShadow),this.color=lr(A,wt,e.color),this.direction=lr(A,Ut,e.direction),this.display=lr(A,lt,e.display),this.float=lr(A,ut,e.cssFloat),this.fontFamily=lr(A,jt,e.fontFamily),this.fontSize=lr(A,zt,e.fontSize),this.fontStyle=lr(A,er,e.fontStyle),this.fontVariant=lr(A,Ar,e.fontVariant),this.fontWeight=lr(A,$t,e.fontWeight),this.letterSpacing=lr(A,Ft,e.letterSpacing),this.lineBreak=lr(A,ht,e.lineBreak),this.lineHeight=lr(A,dt,e.lineHeight),this.listStyleImage=lr(A,ft,e.listStyleImage),this.listStylePosition=lr(A,Ht,e.listStylePosition),this.listStyleType=lr(A,pt,e.listStyleType),this.marginTop=lr(A,Et,e.marginTop),this.marginRight=lr(A,It,e.marginRight),this.marginBottom=lr(A,yt,e.marginBottom),this.marginLeft=lr(A,Kt,e.marginLeft),this.opacity=lr(A,Zt,e.opacity);var t=lr(A,mt,e.overflow);this.overflowX=t[0],this.overflowY=t[1<t.length?1:0],this.overflowWrap=lr(A,Lt,e.overflowWrap),this.paddingTop=lr(A,bt,e.paddingTop),this.paddingRight=lr(A,Dt,e.paddingRight),this.paddingBottom=lr(A,vt,e.paddingBottom),this.paddingLeft=lr(A,xt,e.paddingLeft),this.paintOrder=lr(A,ir,e.paintOrder),this.position=lr(A,St,e.position),this.textAlign=lr(A,Mt,e.textAlign),this.textDecorationColor=lr(A,_t,null!==(t=e.textDecorationColor)&&void 0!==t?t:e.color),this.textDecorationLine=lr(A,qt,null!==(t=e.textDecorationLine)&&void 0!==t?t:e.textDecoration),this.textShadow=lr(A,Tt,e.textShadow),this.textTransform=lr(A,Gt,e.textTransform),this.transform=lr(A,Ot,e.transform),this.transformOrigin=lr(A,Rt,e.transformOrigin),this.visibility=lr(A,Nt,e.visibility),this.webkitTextStrokeColor=lr(A,Qr,e.webkitTextStrokeColor),this.webkitTextStrokeWidth=lr(A,cr,e.webkitTextStrokeWidth),this.wordBreak=lr(A,Jt,e.wordBreak),this.zIndex=lr(A,Yt,e.zIndex)}for(var wr=function(A,e){this.content=lr(A,tr,e.content),this.quotes=lr(A,sr,e.quotes)},Ur=function(A,e){this.counterIncrement=lr(A,rr,e.counterIncrement),this.counterReset=lr(A,Br,e.counterReset)},lr=function(A,e,t){var r=new PA,t=null!=t?t.toString():e.initialValue;r.write(t);var B=new JA(r.read());switch(e.type){case 2:var n=B.parseComponentValue();return e.parse(A,_A(n)?n.value:e.initialValue);case 0:return e.parse(A,B.parseComponentValue());case 1:return e.parse(A,B.parseComponentValues());case 4:return B.parseComponentValue();case 3:switch(e.format){case"angle":return le(A,B.parseComponentValue());case"color":return ue(A,B.parseComponentValue());case"image":return Oe(A,B.parseComponentValue());case"length":var s=B.parseComponentValue();return ee(s)?s:ae;case"length-percentage":s=B.parseComponentValue();return te(s)?s:ae;case"time":return Wt(A,B.parseComponentValue())}}},Cr=function(A,e){A=function(A){switch(A.getAttribute("data-html2canvas-debug")){case"all":return 1;case"clone":return 2;case"parse":return 3;case"render":return 4;default:return 0}}(A);return 1===A||e===A},ur=function(A,e){this.context=A,this.textNodes=[],this.elements=[],this.flags=0,Cr(e,3),this.styles=new ar(A,window.getComputedStyle(e,null)),JB(e)&&(this.styles.animationDuration.some(function(A){return 0<A})&&(e.style.animationDuration="0s"),null!==this.styles.transform&&(e.style.transform="none")),this.bounds=f(this.context,e),Cr(e,4)&&(this.flags|=16)},Fr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",hr="undefined"==typeof Uint8Array?[]:new Uint8Array(256),dr=0;dr<Fr.length;dr++)hr[Fr.charCodeAt(dr)]=dr;function fr(A,e,t){return A.slice?A.slice(e,t):new Uint16Array(Array.prototype.slice.call(A,e,t))}var Hr=(pr.prototype.get=function(A){var e;if(0<=A){if(A<55296||56319<A&&A<=65535)return e=this.index[A>>5],this.data[e=(e<<2)+(31&A)];if(A<=65535)return e=this.index[2048+(A-55296>>5)],this.data[e=(e<<2)+(31&A)];if(A<this.highStart)return e=this.index[e=2080+(A>>11)],e=this.index[e+=A>>5&63],this.data[e=(e<<2)+(31&A)];if(A<=1114111)return this.data[this.highValueIndex]}return this.errorValue},pr);function pr(A,e,t,r,B,n){this.initialValue=A,this.errorValue=e,this.highStart=t,this.highValueIndex=r,this.index=B,this.data=n}for(var Er="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",Ir="undefined"==typeof Uint8Array?[]:new Uint8Array(256),yr=0;yr<Er.length;yr++)Ir[Er.charCodeAt(yr)]=yr;function Kr(A){return kr.get(A)}function mr(A){var t=function(A){for(var e=[],t=0,r=A.length;t<r;){var B,n=A.charCodeAt(t++);55296<=n&&n<=56319&&t<r?56320==(64512&(B=A.charCodeAt(t++)))?e.push(((1023&n)<<10)+(1023&B)+65536):(e.push(n),t--):e.push(n)}return e}(A),r=t.length,B=0,n=0,s=t.map(Kr);return{next:function(){if(r<=B)return{done:!0,value:null};for(var A=Rr;B<r&&(A=function(A,e){var t=e-2,r=A[t],B=A[e-1],e=A[e];if(2===B&&3===e)return Rr;if(2===B||3===B||4===B)return"÷";if(2===e||3===e||4===e)return"÷";if(B===Tr&&-1!==[Tr,Gr,Or,Vr].indexOf(e))return Rr;if(!(B!==Or&&B!==Gr||e!==Gr&&10!==e))return Rr;if((B===Vr||10===B)&&10===e)return Rr;if(13===e||5===e)return Rr;if(7===e)return Rr;if(1===B)return Rr;if(13===B&&14===e){for(;5===r;)r=A[--t];if(14===r)return Rr}if(15===B&&15===e){for(var n=0;15===r;)n++,r=A[--t];if(n%2==0)return Rr}return"÷"}(s,++B))===Rr;);if(A===Rr&&B!==r)return{done:!0,value:null};var e=function(){for(var A=[],e=0;e<arguments.length;e++)A[e]=arguments[e];if(String.fromCodePoint)return String.fromCodePoint.apply(String,A);var t=A.length;if(!t)return"";for(var r=[],B=-1,n="";++B<t;){var s=A[B];s<=65535?r.push(s):(s-=65536,r.push(55296+(s>>10),s%1024+56320)),(B+1===t||16384<r.length)&&(n+=String.fromCharCode.apply(String,r),r.length=0)}return n}.apply(null,t.slice(n,B));return n=B,{value:e,done:!1}}}}function Lr(A){return 0===A[0]&&255===A[1]&&0===A[2]&&255===A[3]}var br,Dr,vr,xr,Mr,Sr,Tr=8,Gr=9,Or=11,Vr=12,kr=(vr=function(A){var e,t,r,B,n=.75*A.length,s=A.length,o=0;"="===A[A.length-1]&&(n--,"="===A[A.length-2]&&n--);for(var n=new("undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array&&void 0!==Uint8Array.prototype.slice?ArrayBuffer:Array)(n),i=Array.isArray(n)?n:new Uint8Array(n),Q=0;Q<s;Q+=4)e=hr[A.charCodeAt(Q)],t=hr[A.charCodeAt(Q+1)],r=hr[A.charCodeAt(Q+2)],B=hr[A.charCodeAt(Q+3)],i[o++]=e<<2|t>>4,i[o++]=(15&t)<<4|r>>2,i[o++]=(3&r)<<6|63&B;return n}(br="AAAAAAAAAAAAEA4AGBkAAFAaAAACAAAAAAAIABAAGAAwADgACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAAQABIAEQATAAIABAACAAQAAgAEAAIABAAVABcAAgAEAAIABAACAAQAGAAaABwAHgAgACIAI4AlgAIABAAmwCjAKgAsAC2AL4AvQDFAMoA0gBPAVYBWgEIAAgACACMANoAYgFkAWwBdAF8AX0BhQGNAZUBlgGeAaMBlQGWAasBswF8AbsBwwF0AcsBYwHTAQgA2wG/AOMBdAF8AekB8QF0AfkB+wHiAHQBfAEIAAMC5gQIAAsCEgIIAAgAFgIeAggAIgIpAggAMQI5AkACygEIAAgASAJQAlgCYAIIAAgACAAKBQoFCgUTBRMFGQUrBSsFCAAIAAgACAAIAAgACAAIAAgACABdAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABoAmgCrwGvAQgAbgJ2AggAHgEIAAgACADnAXsCCAAIAAgAgwIIAAgACAAIAAgACACKAggAkQKZAggAPADJAAgAoQKkAqwCsgK6AsICCADJAggA0AIIAAgACAAIANYC3gIIAAgACAAIAAgACABAAOYCCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAkASoB+QIEAAgACAA8AEMCCABCBQgACABJBVAFCAAIAAgACAAIAAgACAAIAAgACABTBVoFCAAIAFoFCABfBWUFCAAIAAgACAAIAAgAbQUIAAgACAAIAAgACABzBXsFfQWFBYoFigWKBZEFigWKBYoFmAWfBaYFrgWxBbkFCAAIAAgACAAIAAgACAAIAAgACAAIAMEFCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAMgFCADQBQgACAAIAAgACAAIAAgACAAIAAgACAAIAO4CCAAIAAgAiQAIAAgACABAAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAD0AggACAD8AggACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIANYFCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAMDvwAIAAgAJAIIAAgACAAIAAgACAAIAAgACwMTAwgACAB9BOsEGwMjAwgAKwMyAwsFYgE3A/MEPwMIAEUDTQNRAwgAWQOsAGEDCAAIAAgACAAIAAgACABpAzQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQ
vendor: 9,578 bytes, line 33138
33138FNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFIQUoBSwFCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABtAwgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABMAEwACAAIAAgACAAIABgACAAIAAgACAC/AAgACAAyAQgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACACAAIAAwAAgACAAIAAgACAAIAAgACAAIAAAARABIAAgACAAIABQASAAIAAgAIABwAEAAjgCIABsAqAC2AL0AigDQAtwC+IJIQqVAZUBWQqVAZUBlQGVAZUBlQGrC5UBlQGVAZUBlQGVAZUBlQGVAXsKlQGVAbAK6wsrDGUMpQzlDJUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAfAKAAuZA64AtwCJALoC6ADwAAgAuACgA/oEpgO6AqsD+AAIAAgAswMIAAgACAAIAIkAuwP5AfsBwwPLAwgACAAIAAgACADRA9kDCAAIAOED6QMIAAgACAAIAAgACADuA/YDCAAIAP4DyQAIAAgABgQIAAgAXQAOBAgACAAIAAgACAAIABMECAAIAAgACAAIAAgACAD8AAQBCAAIAAgAGgQiBCoECAExBAgAEAEIAAgACAAIAAgACAAIAAgACAAIAAgACAA4BAgACABABEYECAAIAAgATAQYAQgAVAQIAAgACAAIAAgACAAIAAgACAAIAFoECAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAOQEIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAB+BAcACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAEABhgSMBAgACAAIAAgAlAQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAwAEAAQABAADAAMAAwADAAQABAAEAAQABAAEAAQABHATAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAdQMIAAgACAAIAAgACAAIAMkACAAIAAgAfQMIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACACFA4kDCAAIAAgACAAIAOcBCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAIcDCAAIAAgACAAIAAgACAAIAAgACAAIAJEDCAAIAAgACADFAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABgBAgAZgQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAbAQCBXIECAAIAHkECAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABAAJwEQACjBKoEsgQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAC6BMIECAAIAAgACAAIAAgACABmBAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAxwQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAGYECAAIAAgAzgQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAigWKBYoFigWKBYoFigWKBd0FXwUIAOIF6gXxBYoF3gT5BQAGCAaKBYoFigWKBYoFigWKBYoFigWKBYoFigXWBIoFigWKBYoFigWKBYoFigWKBYsFEAaKBYoFigWKBYoFigWKBRQGCACKBYoFigWKBQgACAAIANEECAAIABgGigUgBggAJgYIAC4GMwaKBYoF0wQ3Bj4GigWKBYoFigWKBYoFigWKBYoFigWKBYoFigUIAAgACAAIAAgACAAIAAgAigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWLBf///////wQABAAEAAQABAAEAAQABAAEAAQAAwAEAAQAAgAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAQADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAUAAAAFAAUAAAAFAAUAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEAAQABAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUAAQAAAAUABQAFAAUABQAFAAAAAAAFAAUAAAAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAFAAUAAQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABwAFAAUABQAFAAAABwAHAAcAAAAHAAcABwAFAAEAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAcABwAFAAUAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAQABAAAAAAAAAAAAAAAFAAUABQAFAAAABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAcABwAHAAcAAAAHAAcAAAAAAAUABQAHAAUAAQAHAAEABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABwABAAUABQAFAAUAAAAAAAAAAAAAAAEAAQABAAEAAQABAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABwAFAAUAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUAAQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABQANAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAEAAQABAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEAAQABAAEAAQABAAEAAQABAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAABQAHAAUABQAFAAAAAAAAAAcABQAFAAUABQAFAAQABAAEAAQABAAEAAQABAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUAAAAFAAUABQAFAAUAAAAFAAUABQAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAAAAAAAAAAAAUABQAFAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAUAAAAHAAcABwAFAAUABQAFAAUABQAFAAUABwAHAAcABwAFAAcABwAAAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAUABwAHAAUABQAFAAUAAAAAAAcABwAAAAAABwAHAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAB
vendor: 4,880 bytes, line 33138
33138QAFAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAABwAHAAcABQAFAAAAAAAAAAAABQAFAAAAAAAFAAUABQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAFAAUABQAFAAUAAAAFAAUABwAAAAcABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAFAAUABwAFAAUABQAFAAAAAAAHAAcAAAAAAAcABwAFAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAcABwAAAAAAAAAHAAcABwAAAAcABwAHAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAABQAHAAcABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAHAAcABwAAAAUABQAFAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAcABQAHAAcABQAHAAcAAAAFAAcABwAAAAcABwAFAAUAAAAAAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAUABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAFAAcABwAFAAUABQAAAAUAAAAHAAcABwAHAAcABwAHAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAHAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAABwAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAUAAAAFAAAAAAAAAAAABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABwAFAAUABQAFAAUAAAAFAAUAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABwAFAAUABQAFAAUABQAAAAUABQAHAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABQAFAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAcABQAFAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAHAAUABQAFAAUABQAFAAUABwAHAAcABwAHAAcABwAHAAUABwAHAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABwAHAAcABwAFAAUABwAHAAcAAAAAAAAAAAAHAAcABQAHAAcABwAHAAcABwAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAcABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAHAAUABQAFAAUABQAFAAUAAAAFAAAABQAAAAAABQAFAAUABQAFAAUABQAFAAcABwAHAAcABwAHAAUABQAFAAUABQAFAAUABQAFAAUAAAAAAAUABQAFAAUABQAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABwAFAAcABwAHAAcABwAFAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAUABQAFAAUABwAHAAUABQAHAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAcABQAFAAcABwAHAAUABwAFAAUABQAHAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABwAHAAcABwAHAAUABQAFAAUABQAFAAUABQAHAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAcABQAFAAUABQAFAAUABQAAAAAAAAAAAAUAAAAAAAAAAAAAAAAABQAAAAAABwAFAAUAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUAAAAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAABQAAAAAAAAAFAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAUABQAHAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAHAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAHAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAcABwAFAAUABQAFAAcABwAFAAUABwAHAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAcABwAFAAUABwAHAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAFAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAFAAUABQAAAAAAB
vendor: 74,685 bytes, line 33138
33138QAFAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAFAAcABwAAAAAAAAAAAAAABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAFAAcABwAFAAcABwAAAAcABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAFAAUABQAAAAUABQAAAAAAAAAAAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABwAFAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABQAFAAUABQAFAAUABQAFAAUABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAHAAcABQAHAAUABQAAAAAAAAAAAAAAAAAFAAAABwAHAAcABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAHAAcABwAAAAAABwAHAAAAAAAHAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAAAAAAFAAUABQAFAAUABQAFAAAAAAAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAUABQAFAAUABwAHAAUABQAFAAcABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAcABQAFAAUABQAFAAUABwAFAAcABwAFAAcABQAFAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAcABQAFAAUABQAAAAAABwAHAAcABwAFAAUABwAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAHAAUABQAFAAUABQAFAAUABQAHAAcABQAHAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAFAAcABwAFAAUABQAFAAUABQAHAAUAAAAAAAAAAAAAAAAAAAAAAAcABwAFAAUABQAFAAcABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAUABQAFAAUABQAHAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAAAAAAFAAUABwAHAAcABwAFAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABwAHAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAFAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAcABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAAAHAAUABQAFAAUABQAFAAUABwAFAAUABwAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUAAAAAAAAABQAAAAUABQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAHAAcAAAAFAAUAAAAHAAcABQAHAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAAAAAAAAAAAAAAAAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAUABQAFAAAAAAAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAABQAFAAUABQAFAAUABQAAAAUABQAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAFAAUABQAFAAUADgAOAA4ADgAOAA4ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAAAAAAAAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAMAAwADAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAAAAAAAAAAAAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAAAAAAAAAAAAsADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwACwAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAADgAOAA4AAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAAAA4ADgAOAA4ADgAOAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAAAA4AAAAOAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAADgAAAAAAAAAAAA4AAAAOAAAAAAAAAAAADgAOAA4AAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAAAA4ADgAOAA4ADgAOAA4ADgAOAAAADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4AAAAAAAAAAAAAAAAAAAAAAA4ADgAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAOAA4ADgAOAA4ADgAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAAAAAAAAA="),xr=Array.isArray(vr)?function(A){for(var e=A.length,t=[],r=0;r<e;r+=4)t.push(A[r+3]<<24|A[r+2]<<16|A[r+1]<<8|A[r]);return t}(vr):new Uint32Array(vr),Mr=Array.isArray(vr)?function(A){for(var e=A.length,t=[],r=0;r<e;r+=2)t.push(A[r+1]<<8|A[r]);return t}(vr):new Uint16Array(vr),br=fr(Mr,12,xr[4]/2),Dr=2===xr[5]?fr(Mr,(24+xr[4])/2):(vr=xr,Mr=Math.ceil((24+xr[4])/4),vr.slice?vr.slice(Mr,Dr):new Uint32Array(Array.prototype.slice.call(vr,Mr,Dr))),new Hr(xr[0],xr[1],xr[2],xr[3],br,Dr)),Rr="Ã",Nr=function(A,e,t,r,B){var n="http://www.w3.org/2000/svg",s=document.createElementNS(n,"svg"),n=document.createElementNS(n,"foreignObject");return s.setAttributeNS(null,"width",A.toString()),s.setAttributeNS(null,"height",e.toString()),n.setAttributeNS(null,"width","100%"),n.setAttributeNS(null,"height","100%"),n.setAttributeNS(null,"x",t.toString()),n.setAttributeNS(null,"y",r.toString()),n.setAttributeNS(null,"externalResourcesRequired","true"),s.appendChild(n),n.appendChild(B),s},Pr=function(r){return new Promise(function(A,e){var t=new Image;t.onload=function(){return A(t)},t.onerror=e,t.src="data:image/svg+xml;charset=utf-8,"+encodeURIComponent((new XMLSerializer).serializeToString(r))})},Xr={get SUPPORT_RANGE_BOUNDS(){var A=function(A){if(A.createRange){var e=A.createRange();if(e.getBoundingClientRect){var t=A.createElement("boundtest");t.style.height="123px",t.style.display="block",A.body.appendChild(t),e.selectNode(t);e=e.getBoundingClientRect(),e=Math.round(e.height);if(A.body.removeChild(t),123===e)return!0}}return!1}(document);return Object.defineProperty(Xr,"SUPPORT_RANGE_BOUNDS",{value:A}),A},get SUPPORT_WORD_BREAKING(){var A=Xr.SUPPORT_RANGE_BOUNDS&&function(A){var e=A.createElement("boundtest");e.style.width="50px",e.style.display="block",e.style.fontSize="12px",e.style.letterSpacing="0px",e.style.wordSpacing="0px",A.body.appendChild(e);var r=A.createRange();e.innerHTML="function"==typeof"".repeat?"👨".repeat(10):"";var B=e.firstChild,t=Q(B.data).map(function(A){return g(A)}),n=0,s={},t=t.every(function(A,e){r.setStart(B,n),r.setEnd(B,n+A.length);var t=r.getBoundingClientRect();n+=A.length;A=t.x>s.x||t.y>s.y;return s=t,0===e||A});return A.body.removeChild(e),t}(document);return Object.defineProperty(Xr,"SUPPORT_WORD_BREAKING",{value:A}),A},get SUPPORT_SVG_DRAWING(){var A=function(A){var e=new Image,t=A.createElement("canvas"),A=t.getContext("2d");if(!A)return!1;e.src="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'></svg>";try{A.drawImage(e,0,0),t.toDataURL()}catch(A){return!1}return!0}(document);return Object.defineProperty(Xr,"SUPPORT_SVG_DRAWING",{value:A}),A},get SUPPORT_FOREIGNOBJECT_DRAWING(){var A="function"==typeof Array.from&&"function"==typeof window.fetch?function(t){var A=t.createElement("canvas"),r=100;A.width=r,A.height=r;var B=A.getContext("2d");if(!B)return Promise.reject(!1);B.fillStyle="rgb(0, 255, 0)",B.fillRect(0,0,r,r);var e=new Image,n=A.toDataURL();e.src=n;e=Nr(r,r,0,0,e);return B.fillStyle="red",B.fillRect(0,0,r,r),Pr(e).then(function(A){B.drawImage(A,0,0);var e=B.getImageData(0,0,r,r).data;B.fillStyle="red",B.fillRect(0,0,r,r);A=t.createElement("div");return A.style.backgroundImage="url("+n+")",A.style.height="100px",Lr(e)?Pr(Nr(r,r,0,0,A)):Promise.reject(!1)}).then(function(A){return B.drawImage(A,0,0),Lr(B.getImageData(0,0,r,r).data)}).catch(function(){return!1})}(document):Promise.resolve(!1);return Object.defineProperty(Xr,"SUPPORT_FOREIGNOBJECT_DRAWING",{value:A}),A},get SUPPORT_CORS_IMAGES(){var A=void 0!==(new Image).crossOrigin;return Object.defineProperty(Xr,"SUPPORT_CORS_IMAGES",{value:A}),A},get SUPPORT_RESPONSE_TYPE(){var A="string"==typeof(new XMLHttpRequest).responseType;return Object.defineProperty(Xr,"SUPPORT_RESPONSE_TYPE",{value:A}),A},get SUPPORT_CORS_XHR(){var A="withCredentials"in new XMLHttpRequest;return Object.defineProperty(Xr,"SUPPORT_CORS_XHR",{value:A}),A},get SUPPORT_NATIVE_TEXT_SEGMENTATION(){var A=!("undefined"==typeof Intl||!Intl.Segmenter);return Object.defineProperty(Xr,"SUPPORT_NATIVE_TEXT_SEGMENTATION",{value:A}),A}},Jr=function(A,e){this.text=A,this.bounds=e},Yr=function(A,e){var t=e.ownerDocument;if(t){var r=t.createElement("html2canvaswrapper");r.appendChild(e.cloneNode(!0));t=e.parentNode;if(t){t.replaceChild(r,e);A=f(A,r);return r.firstChild&&t.replaceChild(r.firstChild,r),A}}return d.EMPTY},Wr=function(A,e,t){var r=A.ownerDocument;if(!r)throw new Error("Node has no owner document");r=r.createRange();return r.setStart(A,e),r.setEnd(A,e+t),r},Zr=function(A){if(Xr.SUPPORT_NATIVE_TEXT_SEGMENTATION){var e=new Intl.Segmenter(void 0,{granularity:"grapheme"});return Array.from(e.segment(A)).map(function(A){return A.segment})}return function(A){for(var e,t=mr(A),r=[];!(e=t.next()).done;)e.value&&r.push(e.value.slice());return r}(A)},_r=function(A,e){return 0!==e.letterSpacing?Zr(A):function(A,e){if(Xr.SUPPORT_NATIVE_TEXT_SEGMENTATION){var t=new Intl.Segmenter(void 0,{granularity:"word"});return Array.from(t.segment(A)).map(function(A){return A.segment})}return jr(A,e)}(A,e)},qr=[32,160,4961,65792,65793,4153,4241],jr=function(A,e){for(var t,r=wA(A,{lineBreak:e.lineBreak,wordBreak:"break-word"===e.overflowWrap?"break-word":e.wordBreak}),B=[];!(t=r.next()).done;)!function(){var A,e;t.value&&(A=t.value.slice(),A=Q(A),e="",A.forEach(function(A){-1===qr.indexOf(A)?e+=g(A):(e.length&&B.push(e),B.push(g(A)),e="")}),e.length&&B.push(e))}();return B},zr=function(A,e,t){var B,n,s,o,i;this.text=$r(e.data,t.textTransform),this.textBounds=(B=A,A=this.text,s=e,A=_r(A,n=t),o=[],i=0,A.forEach(function(A){var e,t,r;n.textDecorationLine.length||0<A.trim().length?Xr.SUPPORT_RANGE_BOUNDS?1<(r=Wr(s,i,A.length).getClientRects()).length?(e=Zr(A),t=0,e.forEach(function(A){o.push(new Jr(A,d.fromDOMRectList(B,Wr(s,t+i,A.length).getClientRects()))),t+=A.length})):o.push(new Jr(A,d.fromDOMRectList(B,r))):(r=s.splitText(A.length),o.push(new Jr(A,Yr(B,s))),s=r):Xr.SUPPORT_RANGE_BOUNDS||(s=s.splitText(A.length)),i+=A.length}),o)},$r=function(A,e){switch(e){case 1:return A.toLowerCase();case 3:return A.replace(AB,eB);case 2:return A.toUpperCase();default:return A}},AB=/(^|\s|:|-|\(|\))([a-z])/g,eB=function(A,e,t){return 0<A.length?e+t.toUpperCase():A},tB=(A(rB,Sr=ur),rB);function rB(A,e){A=Sr.call(this,A,e)||this;return A.src=e.currentSrc||e.src,A.intrinsicWidth=e.naturalWidth,A.intrinsicHeight=e.naturalHeight,A.context.cache.addImage(A.src),A}var BB,nB=(A(sB,BB=ur),sB);function sB(A,e){A=BB.call(this,A,e)||this;return A.canvas=e,A.intrinsicWidth=e.width,A.intrinsicHeight=e.height,A}var oB,iB=(A(QB,oB=ur),QB);function QB(A,e){var t=oB.call(this,A,e)||this,r=new XMLSerializer,A=f(A,e);return e.setAttribute("width",A.width+"px"),e.setAttribute("height",A.height+"px"),t.svg="data:image/svg+xml,"+encodeURIComponent(r.serializeToString(e)),t.intrinsicWidth=e.width.baseVal.value,t.intrinsicHeight=e.height.baseVal.value,t.context.cache.addImage(t.svg),t}var cB,aB=(A(gB,cB=ur),gB);function gB(A,e){A=cB.call(this,A,e)||this;return A.value=e.value,A}var wB,UB=(A(lB,wB=ur),lB);function lB(A,e){A=wB.call(this,A,e)||this;return A.start=e.start,A.reversed="boolean"==typeof e.reversed&&!0===e.reversed,A}var CB,uB=[{type:15,flags:0,unit:"px",number:3}],FB=[{type:16,flags:0,number:50}],hB="checkbox",dB="radio",fB="password",HB=707406591,pB=(A(EB,CB=ur),EB);function EB(A,e){var t=CB.call(this,A,e)||this;switch(t.type=e.type.toLowerCase(),t.checked=e.checked,t.value=0===(e=(A=e).type===fB?new Array(A.value.length+1).join("â¢"):A.value).length?A.placeholder||"":e,t.type!==hB&&t.type!==dB||(t.styles.backgroundColor=3739148031,t.styles.borderTopColor=t.styles.borderRightColor=t.styles.borderBottomColor=t.styles.borderLeftColor=2779096575,t.styles.borderTopWidth=t.styles.borderRightWidth=t.styles.borderBottomWidth=t.styles.borderLeftWidth=1,t.styles.borderTopStyle=t.styles.borderRightStyle=t.styles.borderBottomStyle=t.styles.borderLeftStyle=1,t.styles.backgroundClip=[0],t.styles.backgroundOrigin=[0],t.bounds=(e=t.bounds).width>e.height?new d(e.left+(e.width-e.height)/2,e.top,e.height,e.height):e.width<e.height?new d(e.left,e.top+(e.height-e.width)/2,e.width,e.width):e),t.type){case hB:t.styles.borderTopRightRadius=t.styles.borderTopLeftRadius=t.styles.borderBottomRightRadius=t.styles.borderBottomLeftRadius=uB;break;case dB:t.styles.borderTopRightRadius=t.styles.borderTopLeftRadius=t.styles.borderBottomRightRadius=t.styles.borderBottomLeftRadius=FB}return t}var IB,yB=(A(KB,IB=ur),KB);function KB(A,e){A=IB.call(this,A,e)||this,e=e.options[e.selectedIndex||0];return A.value=e&&e.text||"",A}var mB,LB=(A(bB,mB=ur),bB);function bB(A,e){A=mB.call(this,A,e)||this;return A.value=e.value,A}var DB,vB=(A(xB,DB=ur),xB);function xB(A,e){var t,r,B=DB.call(this,A,e)||this;B.src=e.src,B.width=parseInt(e.width,10)||0,B.height=parseInt(e.height,10)||0,B.backgroundColor=B.styles.backgroundColor;try{e.contentWindow&&e.contentWindow.document&&e.contentWindow.document.documentElement&&(B.tree=kB(A,e.contentWindow.document.documentElement),t=e.contentWindow.document.documentElement?fe(A,getComputedStyle(e.contentWindow.document.documentElement).backgroundColor):Le.TRANSPARENT,r=e.contentWindow.document.body?fe(A,getComputedStyle(e.contentWindow.document.body).backgroundColor):Le.TRANSPARENT,B.backgroundColor=oe(t)?oe(r)?B.styles.backgroundColor:r:t)}catch(A){}return B}function MB(A){return"VIDEO"===A.tagName}function SB(A){return"STYLE"===A.tagName}function TB(A){return 0<A.tagName.indexOf("-")}var GB=["OL","UL","MENU"],OB=function(e,A,t,r){for(var B=A.firstChild;B;B=s){var n,s=B.nextSibling;PB(B)&&0<B.data.trim().length?t.textNodes.push(new zr(e,B,t.styles)):XB(B)&&(rn(B)&&B.assignedNodes?B.assignedNodes().forEach(function(A){return OB(e,A,t,r)}):(n=VB(e,B)).styles.isVisible()&&(RB(B,n,r)?n.flags|=4:NB(n.styles)&&(n.flags|=2),-1!==GB.indexOf(B.tagName)&&(n.flags|=8),t.elements.push(n),B.slot,B.shadowRoot?OB(e,B.shadowRoot,n,r):en(B)||qB(B)||tn(B)||OB(e,B,n,r)))}},VB=function(A,e){return new($B(e)?tB:zB(e)?nB:qB(e)?iB:WB(e)?aB:ZB(e)?UB:_B(e)?pB:tn(e)?yB:en(e)?LB:An(e)?vB:ur)(A,e)},kB=function(A,e){var t=VB(A,e);return t.flags|=4,OB(A,e,t,t),t},RB=function(A,e,t){return e.styles.isPositionedWithZIndex()||e.styles.opacity<1||e.styles.isTransformed()||jB(A)&&t.styles.isTransparent()},NB=function(A){return A.isPositioned()||A.isFloating()},PB=function(A){return A.nodeType===Node.TEXT_NODE},XB=function(A){return A.nodeType===Node.ELEMENT_NODE},JB=function(A){return XB(A)&&void 0!==A.style&&!YB(A)},YB=function(A){return"object"==typeof A.className},WB=function(A){return"LI"===A.tagName},ZB=function(A){return"OL"===A.tagName},_B=function(A){return"INPUT"===A.tagName},qB=function(A){return"svg"===A.tagName},jB=function(A){return"BODY"===A.tagName},zB=function(A){return"CANVAS"===A.tagName},$B=function(A){return"IMG"===A.tagName},An=function(A){return"IFRAME"===A.tagName},en=function(A){return"TEXTAREA"===A.tagName},tn=function(A){return"SELECT"===A.tagName},rn=function(A){return"SLOT"===A.tagName},Bn=(nn.prototype.getCounterValue=function(A){A=this.counters[A];return A&&A.length?A[A.length-1]:1},nn.prototype.getCounterValues=function(A){A=this.counters[A];return A||[]},nn.prototype.pop=function(A){var e=this;A.forEach(function(A){return e.counters[A].pop()})},nn.prototype.parse=function(A){var t=this,e=A.counterIncrement,A=A.counterReset,r=!0;null!==e&&e.forEach(function(A){var e=t.counters[A.counter];e&&0!==A.increment&&(r=!1,e.length||e.push(1),e[Math.max(0,e.length-1)]+=A.increment)});var B=[];return r&&A.forEach(function(A){var e=t.counters[A.counter];B.push(A.counter),(e=e||(t.counters[A.counter]=[])).push(A.reset)}),B},nn);function nn(){this.counters={}}function sn(r,A,e,B,t,n){return r<A||e<r?Fn(r,t,0<n.length):B.integers.reduce(function(A,e,t){for(;e<=r;)r-=e,A+=B.values[t];return A},"")+n}function on(A,e,t,r){for(var B="";t||A--,B=r(A)+B,e<=(A/=e)*e;);return B}function Qn(A,e,t,r,B){var n=t-e+1;return(A<0?"-":"")+(on(Math.abs(A),n,r,function(A){return g(Math.floor(A%n)+e)})+B)}function cn(A,e,t){void 0===t&&(t=". ");var r=e.length;return on(Math.abs(A),r,!1,function(A){return e[Math.floor(A%r)]})+t}function an(A,e,t,r,B,n){if(A<-9999||9999<A)return Fn(A,4,0<B.length);var s=Math.abs(A),o=B;if(0===s)return e[0]+o;for(var i=0;0<s&&i<=4;i++){var Q=s%10;0==Q&&Pt(n,1)&&""!==o?o=e[Q]+o:1<Q||1==Q&&0===i||1==Q&&1===i&&Pt(n,2)||1==Q&&1===i&&Pt(n,4)&&100<A||1==Q&&1<i&&Pt(n,8)?o=e[Q]+(0<i?t[i-1]:"")+o:1==Q&&0<i&&(o=t[i-1]+o),s=Math.floor(s/10)}return(A<0?r:"")+o}var gn,wn={integers:[1e3,900,500,400,100,90,50,40,10,9,5,4,1],values:["M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"]},Un={integers:[9e3,8e3,7e3,6e3,5e3,4e3,3e3,2e3,1e3,900,800,700,600,500,400,300,200,100,90,80,70,60,50,40,30,20,10,9,8,7,6,5,4,3,2,1],values:["Õ","Õ","Õ","Õ","Õ","Õ","Õ","Õ","Õ","Õ","Õ","Õ","Õ","Õ","Õ","Õ
","Õ","Õ","Õ","Õ","Õ","Ô¿","Ô¾","Ô½","Ô¼","Ô»","Ôº","Ô¹","Ô¸","Ô·","Ô¶","Ôµ","Ô´","Ô³","Ô²","Ô±"]},ln={integers:[1e4,9e3,8e3,7e3,6e3,5e3,4e3,3e3,2e3,1e3,400,300,200,100,90,80,70,60,50,40,30,20,19,18,17,16,15,10,9,8,7,6,5,4,3,2,1],values:["×׳","×׳","×׳","×׳","×׳","×׳","×׳","×׳","×׳","×׳","ת","ש","ר","×§","צ","פ","×¢","ס","× ","×","×","×","××","××","××","××","××","×","×","×","×","×","×","×","×","×","×"]},Cn={integers:[1e4,9e3,8e3,7e3,6e3,5e3,4e3,3e3,2e3,1e3,900,800,700,600,500,400,300,200,100,90,80,70,60,50,40,30,20,10,9,8,7,6,5,4,3,2,1],values:["áµ","á°","á¯","á´","á®","á","á¬","á«","áª","á©","á¨","á§","á¦","á¥","á¤","á³","á¢","á¡","á ","á","á","á","á²","á","á","á","á","á","á","á±","á","á","á","á","á","á","á"]},un="ë§ì´ëì¤",Fn=function(A,e,t){var r=t?". ":"",B=t?"ã":"",n=t?", ":"",s=t?" ":"";switch(e){case 0:return"â¢"+s;case 1:return"â¦"+s;case 2:return"â¾"+s;case 5:var o=Qn(A,48,57,!0,r);return o.length<4?"0"+o:o;case 4:return cn(A,"ãä¸äºä¸åäºå
ä¸å
«ä¹",B);case 6:return sn(A,1,3999,wn,3,r).toLowerCase();case 7:return sn(A,1,3999,wn,3,r);case 8:return Qn(A,945,969,!1,r);case 9:return Qn(A,97,122,!1,r);case 10:return Qn(A,65,90,!1,r);case 11:return Qn(A,1632,1641,!0,r);case 12:case 49:return sn(A,1,9999,Un,3,r);case 35:return sn(A,1,9999,Un,3,r).toLowerCase();case 13:return Qn(A,2534,2543,!0,r);case 14:case 30:return Qn(A,6112,6121,!0,r);case 15:return cn(A,"åä¸å¯
å¯è¾°å·³åæªç³é
æäº¥",B);case 16:return cn(A,"ç²ä¹ä¸ä¸æå·±åºè¾å£¬ç¸",B);case 17:case 48:return an(A,"é¶ä¸äºä¸åäºå
ä¸å
«ä¹","åç¾åè¬","è² ",B,14);case 47:return an(A,"é¶å£¹è²³åèä¼é¸ææç","æ¾ä½°ä»è¬","è² ",B,15);case 42:return an(A,"é¶ä¸äºä¸åäºå
ä¸å
«ä¹","åç¾åè¬","è´",B,14);case 41:return an(A,"é¶å£¹è´°åèä¼éææç","æ¾ä½°ä»è¬","è´",B,15);case 26:return an(A,"ãä¸äºä¸åäºå
ä¸å
«ä¹","åç¾åä¸","ãã¤ãã¹",B,0);case 25:return an(A,"é¶å£±å¼ååä¼å
ä¸å
«ä¹","æ¾ç¾åä¸","ãã¤ãã¹",B,7);case 31:return an(A,"ìì¼ì´ì¼ì¬ì¤ì¡ì¹ í구","ìë°±ì²ë§",un,n,7);case 33:return an(A,"é¶ä¸äºä¸åäºå
ä¸å
«ä¹","åç¾åè¬",un,n,0);case 32:return an(A,"é¶å£¹è²³ååäºå
ä¸å
«ä¹","æ¾ç¾å",un,n,7);case 18:return Qn(A,2406,2415,!0,r);case 20:return sn(A,1,19999,Cn,3,r);case 21:return Qn(A,2790,2799,!0,r);case 22:return Qn(A,2662,2671,!0,r);case 22:return sn(A,1,10999,ln,3,r);case 23:return cn(A,"ããããããããããããããããã¡ã¤ã¦ã¨ãªã«ã¬ãã®ã¯ã²ãµã¸ã»ã¾ã¿ãããããããããããããããã");case 24:return cn(A,"ããã¯ã«ã»ã¸ã¨ã¡ãã¬ããããããããã¤ããªããããã®ãããã¾ããµããã¦ãããããã¿ããã²ããã");case 27:return Qn(A,3302,3311,!0,r);case 28:return cn(A,"ã¢ã¤ã¦ã¨ãªã«ãã¯ã±ã³ãµã·ã¹ã»ã½ã¿ããããããããããããããããã ã¡ã¢ã¤ã¦ã¨ã©ãªã«ã¬ãã¯ã°ã±ã²ã³",B);case 29:return cn(A,"ã¤ããããããããªãã«ã²ã¯ã«ã¨ã¿ã¬ã½ãããã©ã ã¦ã°ããªã¯ã¤ãã±ãã³ã¨ãã¢ãµãã¦ã¡ãã·ã±ãã¢ã»ã¹",B);case 34:return Qn(A,3792,3801,!0,r);case 37:return Qn(A,6160,6169,!0,r);case 38:return Qn(A,4160,4169,!0,r);case 39:return Qn(A,2918,2927,!0,r);case 40:return Qn(A,1776,1785,!0,r);case 43:return Qn(A,3046,3055,!0,r);case 44:return Qn(A,3174,3183,!0,r);case 45:return Qn(A,3664,3673,!0,r);case 46:return Qn(A,3872,3881,!0,r);default:return Qn(A,48,57,!0,r)}},hn="data-html2canvas-ignore",dn=(fn.prototype.toIFrame=function(A,r){var e=this,B=pn(A,r);if(!B.contentWindow)return Promise.reject("Unable to find iframe window");var t=A.defaultView.pageXOffset,n=A.defaultView.pageYOffset,s=B.contentWindow,o=s.document,A=In(B).then(function(){return a(e,void 0,void 0,function(){var e,t;return H(this,function(A){switch(A.label){case 0:return this.scrolledElements.forEach(bn),s&&(s.scrollTo(r.left,r.top),!/(iPad|iPhone|iPod)/g.test(navigator.userAgent)||s.scrollY===r.top&&s.scrollX===r.left||(this.context.logger.warn("Unable to restore scroll position for cloned document"),this.context.windowBounds=this.context.windowBounds.add(s.scrollX-r.left,s.scrollY-r.top,0,0))),e=this.options.onclone,void 0===(t=this.clonedReferenceElement)?[2,Promise.reject("Error finding the "+this.referenceElement.nodeName+" in the cloned document")]:o.fonts&&o.fonts.ready?[4,o.fonts.ready]:[3,2];case 1:A.sent(),A.label=2;case 2:return/(AppleWebKit)/g.test(navigator.userAgent)?[4,En(o)]:[3,4];case 3:A.sent(),A.label=4;case 4:return"function"==typeof e?[2,Promise.resolve().then(function(){return e(o,t)}).then(function(){return B})]:[2,B]}})})});return o.open(),o.write(mn(document.doctype)+"<html></html>"),Ln(this.referenceElement.ownerDocument,t,n),o.replaceChild(o.adoptNode(this.documentElement),o.documentElement),o.close(),A},fn.prototype.createElementClone=function(A){if(Cr(A,2),zB(A))return this.createCanvasClone(A);if(MB(A))return this.createVideoClone(A);if(SB(A))return this.createStyleClone(A);var e=A.cloneNode(!1);return $B(e)&&($B(A)&&A.currentSrc&&A.currentSrc!==A.src&&(e.src=A.currentSrc,e.srcset=""),"lazy"===e.loading&&(e.loading="eager")),TB(e)?this.createCustomElementClone(e):e},fn.prototype.createCustomElementClone=function(A){var e=document.createElement("html2canvascustomelement");return Kn(A.style,e),e},fn.prototype.createStyleClone=function(A){try{var e=A.sheet;if(e&&e.cssRules){var t=[].slice.call(e.cssRules,0).reduce(function(A,e){return e&&"string"==typeof e.cssText?A+e.cssText:A},""),r=A.cloneNode(!1);return r.textContent=t,r}}catch(A){if(this.context.logger.error("Unable to access cssRules property",A),"SecurityError"!==A.name)throw A}return A.cloneNode(!1)},fn.prototype.createCanvasClone=function(e){var A;if(this.options.inlineImages&&e.ownerDocument){var t=e.ownerDocument.createElement("img");try{return t.src=e.toDataURL(),t}catch(A){this.context.logger.info("Unable to inline canvas contents, canvas is tainted",e)}}t=e.cloneNode(!1);try{t.width=e.width,t.height=e.height;var r,B,n=e.getContext("2d"),s=t.getContext("2d");return s&&(!this.options.allowTaint&&n?s.putImageData(n.getImageData(0,0,e.width,e.height),0,0):(!(r=null!==(A=e.getContext("webgl2"))&&void 0!==A?A:e.getContext("webgl"))||!1===(null==(B=r.getContextAttributes())?void 0:B.preserveDrawingBuffer)&&this.context.logger.warn("Unable to clone WebGL context as it has preserveDrawingBuffer=false",e),s.drawImage(e,0,0))),t}catch(A){this.context.logger.info("Unable to clone canvas as it is tainted",e)}return t},fn.prototype.createVideoClone=function(e){var A=e.ownerDocument.createElement("canvas");A.width=e.offsetWidth,A.height=e.offsetHeight;var t=A.getContext("2d");try{return t&&(t.drawImage(e,0,0,A.width,A.height),this.options.allowTaint||t.getImageData(0,0,A.width,A.height)),A}catch(A){this.context.logger.info("Unable to clone video as it is tainted",e)}A=e.ownerDocument.createElement("canvas");return A.width=e.offsetWidth,A.height=e.offsetHeight,A},fn.prototype.appendChildNode=function(A,e,t){XB(e)&&("SCRIPT"===e.tagName||e.hasAttribute(hn)||"function"==typeof this.options.ignoreElements&&this.options.ignoreElements(e))||this.options.copyStyles&&XB(e)&&SB(e)||A.appendChild(this.cloneNode(e,t))},fn.prototype.cloneChildNodes=function(A,e,t){for(var r,B=this,n=(A.shadowRoot||A).firstChild;n;n=n.nextSibling)XB(n)&&rn(n)&&"function"==typeof n.assignedNodes?(r=n.assignedNodes()).length&&r.forEach(function(A){return B.appendChildNode(e,A,t)}):this.appendChildNode(e,n,t)},fn.prototype.cloneNode=function(A,e){if(PB(A))return document.createTextNode(A.data);if(!A.ownerDocument)return A.cloneNode(!1);var t=A.ownerDocument.defaultView;if(t&&XB(A)&&(JB(A)||YB(A))){var r=this.createElementClone(A);r.style.transitionProperty="none";var B=t.getComputedStyle(A),n=t.getComputedStyle(A,":before"),s=t.getComputedStyle(A,":after");this.referenceElement===A&&JB(r)&&(this.clonedReferenceElement=r),jB(r)&&Mn(r);t=this.counters.parse(new Ur(this.context,B)),n=this.resolvePseudoContent(A,r,n,gn.BEFORE);TB(A)&&(e=!0),MB(A)||this.cloneChildNodes(A,r,e),n&&r.insertBefore(n,r.firstChild);s=this.resolvePseudoContent(A,r,s,gn.AFTER);return s&&r.appendChild(s),this.counters.pop(t),(B&&(this.options.copyStyles||YB(A))&&!An(A)||e)&&Kn(B,r),0===A.scrollTop&&0===A.scrollLeft||this.scrolledElements.push([r,A.scrollLeft,A.scrollTop]),(en(A)||tn(A))&&(en(r)||tn(r))&&(r.value=A.value),r}return A.cloneNode(!1)},fn.prototype.resolvePseudoContent=function(o,A,e,t){var i=this;if(e){var r=e.content,Q=A.ownerDocument;if(Q&&r&&"none"!==r&&"-moz-alt-content"!==r&&"none"!==e.display){this.counters.parse(new Ur(this.context,e));var c=new wr(this.context,e),a=Q.createElement("html2canvaspseudoelement");Kn(e,a),c.content.forEach(function(A){if(0===A.type)a.appendChild(Q.createTextNode(A.value));else if(22===A.type){var e=Q.createElement("img");e.src=A.value,e.style.opacity="1",a.appendChild(e)}else if(18===A.type){var t,r,B,n,s;"attr"===A.name?(e=A.values.filter(_A)).length&&a.appendChild(Q.createTextNode(o.getAttribute(e[0].value)||"")):"counter"===A.name?(B=(r=A.values.filter($A))[0],r=r[1],B&&_A(B)&&(t=i.counters.getCounterValue(B.value),s=r&&_A(r)?pt.parse(i.context,r.value):3,a.appendChild(Q.createTextNode(Fn(t,s,!1))))):"counters"===A.name&&(B=(t=A.values.filter($A))[0],s=t[1],r=t[2],B&&_A(B)&&(B=i.counters.getCounterValues(B.value),n=r&&_A(r)?pt.parse(i.context,r.value):3,s=s&&0===s.type?s.value:"",s=B.map(function(A){return Fn(A,n,!1)}).join(s),a.appendChild(Q.createTextNode(s))))}else if(20===A.type)switch(A.value){case"open-quote":a.appendChild(Q.createTextNode(Xt(c.quotes,i.quoteDepth++,!0)));break;case"close-quote":a.appendChild(Q.createTextNode(Xt(c.quotes,--i.quoteDepth,!1)));break;default:a.appendChild(Q.createTextNode(A.value))}}),a.className=Dn+" "+vn;t=t===gn.BEFORE?" "+Dn:" "+vn;return YB(A)?A.className.baseValue+=t:A.className+=t,a}}},fn.destroy=function(A){return!!A.parentNode&&(A.parentNode.removeChild(A),!0)},fn);function fn(A,e,t){if(this.context=A,this.options=t,this.scrolledElements=[],this.referenceElement=e,this.counters=new Bn,this.quoteDepth=0,!e.ownerDocument)throw new Error("Cloned element does not have an owner document");this.documentElement=this.cloneNode(e.ownerDocument.documentElement,!1)}(he=gn=gn||{})[he.BEFORE=0]="BEFORE",he[he.AFTER=1]="AFTER";function Hn(e){return new Promise(function(A){!e.complete&&e.src?(e.onload=A,e.onerror=A):A()})}var pn=function(A,e){var t=A.createElement("iframe");return t.className="html2canvas-container",t.style.visibility="hidden",t.style.position="fixed",t.style.left="-10000px",t.style.top="0px",t.style.border="0",t.width=e.width.toString(),t.height=e.height.toString(),t.scrolling="no",t.setAttribute(hn,"true"),A.body.appendChild(t),t},En=function(A){return Promise.all([].slice.call(A.images,0).map(Hn))},In=function(B){return new Promise(function(e,A){var t=B.contentWindow;if(!t)return A("No window assigned for iframe");var r=t.document;t.onload=B.onload=function(){t.onload=B.onload=null;var A=setInterval(function(){0<r.body.childNodes.length&&"complete"===r.readyState&&(clearInterval(A),e(B))},50)}})},yn=["all","d","content"],Kn=function(A,e){for(var t=A.length-1;0<=t;t--){var r=A.item(t);-1===yn.indexOf(r)&&e.style.setProperty(r,A.getPropertyValue(r))}return e},mn=function(A){var e="";return A&&(e+="<!DOCTYPE ",A.name&&(e+=A.name),A.internalSubset&&(e+=A.internalSubset),A.publicId&&(e+='"'+A.publicId+'"'),A.systemId&&(e+='"'+A.systemId+'"'),e+=">"),e},Ln=function(A,e,t){A&&A.defaultView&&(e!==A.defaultView.pageXOffset||t!==A.defaultView.pageYOffset)&&A.defaultView.scrollTo(e,t)},bn=function(A){var e=A[0],t=A[1],A=A[2];e.scrollLeft=t,e.scrollTop=A},Dn="___html2canvas___pseudoelement_before",vn="___html2canvas___pseudoelement_after",xn='{\n content: "" !important;\n display: none !important;\n}',Mn=function(A){Sn(A,"."+Dn+":before"+xn+"\n ."+vn+":after"+xn)},Sn=function(A,e){var t=A.ownerDocument;t&&((t=t.createElement("style")).textContent=e,A.appendChild(t))},Tn=(Gn.getOrigin=function(A){var e=Gn._link;return e?(e.href=A,e.href=e.href,e.protocol+e.hostname+e.port):"about:blank"},Gn.isSameOrigin=function(A){return Gn.getOrigin(A)===Gn._origin},Gn.setContext=function(A){Gn._link=A.document.createElement("a"),Gn._origin=Gn.getOrigin(A.location.href)},Gn._origin="about:blank",Gn);function Gn(){}var On=(Vn.prototype.addImage=function(A){var e=Promise.resolve();return this.has(A)||(Yn(A)||Pn(A))&&(this._cache[A]=this.loadImage(A)).catch(function(){}),e},Vn.prototype.match=function(A){return this._cache[A]},Vn.prototype.loadImage=function(s){return a(this,void 0,void 0,function(){var e,r,t,B,n=this;return H(this,function(A){switch(A.label){case 0:return(e=Tn.isSameOrigin(s),r=!Xn(s)&&!0===this._options.useCORS&&Xr.SUPPORT_CORS_IMAGES&&!e,t=!Xn(s)&&!e&&!Yn(s)&&"string"==typeof this._options.proxy&&Xr.SUPPORT_CORS_XHR&&!r,e||!1!==this._options.allowTaint||Xn(s)||Yn(s)||t||r)?(B=s,t?[4,this.proxy(B)]:[3,2]):[2];case 1:B=A.sent(),A.label=2;case 2:return this.context.logger.debug("Added image "+s.substring(0,256)),[4,new Promise(function(A,e){var t=new Image;t.onload=function(){return A(t)},t.onerror=e,(Jn(B)||r)&&(t.crossOrigin="anonymous"),t.src=B,!0===t.complete&&setTimeout(function(){return A(t)},500),0<n._options.imageTimeout&&setTimeout(function(){return e("Timed out ("+n._options.imageTimeout+"ms) loading image")},n._options.imageTimeout)})];case 3:return[2,A.sent()]}})})},Vn.prototype.has=function(A){return void 0!==this._cache[A]},Vn.prototype.keys=function(){return Promise.resolve(Object.keys(this._cache))},Vn.prototype.proxy=function(s){var o=this,i=this._options.proxy;if(!i)throw new Error("No proxy defined");var Q=s.substring(0,256);return new Promise(function(e,t){var r=Xr.SUPPORT_RESPONSE_TYPE?"blob":"text",B=new XMLHttpRequest;B.onload=function(){var A;200===B.status?"text"==r?e(B.response):((A=new FileReader).addEventListener("load",function(){return e(A.result)},!1),A.addEventListener("error",function(A){return t(A)},!1),A.readAsDataURL(B.response)):t("Failed to proxy resource "+Q+" with status code "+B.status)},B.onerror=t;var A,n=-1<i.indexOf("?")?"&":"?";B.open("GET",i+n+"url="+encodeURIComponent(s)+"&responseType="+r),"text"!=r&&B instanceof XMLHttpRequest&&(B.responseType=r),o._options.imageTimeout&&(A=o._options.imageTimeout,B.timeout=A,B.ontimeout=function(){return t("Timed out ("+A+"ms) proxying "+Q)}),B.send()})},Vn);function Vn(A,e){this.context=A,this._options=e,this._cache={}}var kn=/^data:image\/svg\+xml/i,Rn=/^data:image\/.*;base64,/i,Nn=/^data:image\/.*/i,Pn=function(A){return Xr.SUPPORT_SVG_DRAWING||!Wn(A)},Xn=function(A){return Nn.test(A)},Jn=function(A){return Rn.test(A)},Yn=function(A){return"blob"===A.substr(0,4)},Wn=function(A){return"svg"===A.substr(-3).toLowerCase()||kn.test(A)},Zn=(_n.prototype.add=function(A,e){return new _n(this.x+A,this.y+e)},_n);function _n(A,e){this.type=0,this.x=A,this.y=e}function qn(A,e,t){return new Zn(A.x+(e.x-A.x)*t,A.y+(e.y-A.y)*t)}var jn=(zn.prototype.subdivide=function(A,e){var t=qn(this.start,this.startControl,A),r=qn(this.startControl,this.endControl,A),B=qn(this.endControl,this.end,A),n=qn(t,r,A),r=qn(r,B,A),A=qn(n,r,A);return e?new zn(this.start,t,n,A):new zn(A,r,B,this.end)},zn.prototype.add=function(A,e){return new zn(this.start.add(A,e),this.startControl.add(A,e),this.endControl.add(A,e),this.end.add(A,e))},zn.prototype.reverse=function(){return new zn(this.end,this.endControl,this.startControl,this.start)},zn);function zn(A,e,t,r){this.type=1,this.start=A,this.startControl=e,this.endControl=t,this.end=r}function $n(A){return 1===A.type}var As,es=function(A){var e=A.styles,t=A.bounds,r=(C=Be(e.borderTopLeftRadius,t.width,t.height))[0],B=C[1],n=(u=Be(e.borderTopRightRadius,t.width,t.height))[0],s=u[1],o=(F=Be(e.borderBottomRightRadius,t.width,t.height))[0],i=F[1],Q=(h=Be(e.borderBottomLeftRadius,t.width,t.height))[0],c=h[1];(d=[]).push((r+n)/t.width),d.push((Q+o)/t.width),d.push((B+c)/t.height),d.push((s+i)/t.height),1<(f=Math.max.apply(Math,d))&&(r/=f,B/=f,n/=f,s/=f,o/=f,i/=f,Q/=f,c/=f);var a=t.width-n,g=t.height-i,w=t.width-o,U=t.height-c,l=e.borderTopWidth,C=e.borderRightWidth,u=e.borderBottomWidth,F=e.borderLeftWidth,h=Ue(e.paddingTop,A.bounds.width),d=Ue(e.paddingRight,A.bounds.width),f=Ue(e.paddingBottom,A.bounds.width),A=Ue(e.paddingLeft,A.bounds.width);this.topLeftBorderDoubleOuterBox=0<r||0<B?ss(t.left+F/3,t.top+l/3,r-F/3,B-l/3,As.TOP_LEFT):new Zn(t.left+F/3,t.top+l/3),this.topRightBorderDoubleOuterBox=0<r||0<B?ss(t.left+a,t.top+l/3,n-C/3,s-l/3,As.TOP_RIGHT):new Zn(t.left+t.width-C/3,t.top+l/3),this.bottomRightBorderDoubleOuterBox=0<o||0<i?ss(t.left+w,t.top+g,o-C/3,i-u/3,As.BOTTOM_RIGHT):new Zn(t.left+t.width-C/3,t.top+t.height-u/3),this.bottomLeftBorderDoubleOuterBox=0<Q||0<c?ss(t.left+F/3,t.top+U,Q-F/3,c-u/3,As.BOTTOM_LEFT):new Zn(t.left+F/3,t.top+t.height-u/3),this.topLeftBorderDoubleInnerBox=0<r||0<B?ss(t.left+2*F/3,t.top+2*l/3,r-2*F/3,B-2*l/3,As.TOP_LEFT):new Zn(t.left+2*F/3,t.top+2*l/3),this.topRightBorderDoubleInnerBox=0<r||0<B?ss(t.left+a,t.top+2*l/3,n-2*C/3,s-2*l/3,As.TOP_RIGHT):new Zn(t.left+t.width-2*C/3,t.top+2*l/3),this.bottomRightBorderDoubleInnerBox=0<o||0<i?ss(t.left+w,t.top+g,o-2*C/3,i-2*u/3,As.BOTTOM_RIGHT):new Zn(t.left+t.width-2*C/3,t.top+t.height-2*u/3),this.bottomLeftBorderDoubleInnerBox=0<Q||0<c?ss(t.left+2*F/3,t.top+U,Q-2*F/3,c-2*u/3,As.BOTTOM_LEFT):new Zn(t.left+2*F/3,t.top+t.height-2*u/3),this.topLeftBorderStroke=0<r||0<B?ss(t.left+F/2,t.top+l/2,r-F/2,B-l/2,As.TOP_LEFT):new Zn(t.left+F/2,t.top+l/2),this.topRightBorderStroke=0<r||0<B?ss(t.left+a,t.top+l/2,n-C/2,s-l/2,As.TOP_RIGHT):new Zn(t.left+t.width-C/2,t.top+l/2),this.bottomRightBorderStroke=0<o||0<i?ss(t.left+w,t.top+g,o-C/2,i-u/2,As.BOTTOM_RIGHT):new Zn(t.left+t.width-C/2,t.top+t.height-u/2),this.bottomLeftBorderStroke=0<Q||0<c?ss(t.left+F/2,t.top+U,Q-F/2,c-u/2,As.BOTTOM_LEFT):new Zn(t.left+F/2,t.top+t.height-u/2),this.topLeftBorderBox=0<r||0<B?ss(t.left,t.top,r,B,As.TOP_LEFT):new Zn(t.left,t.top),this.topRightBorderBox=0<n||0<s?ss(t.left+a,t.top,n,s,As.TOP_RIGHT):new Zn(t.left+t.width,t.top),this.bottomRightBorderBox=0<o||0<i?ss(t.left+w,t.top+g,o,i,As.BOTTOM_RIGHT):new Zn(t.left+t.width,t.top+t.height),this.bottomLeftBorderBox=0<Q||0<c?ss(t.left,t.top+U,Q,c,As.BOTTOM_LEFT):new Zn(t.left,t.top+t.height),this.topLeftPaddingBox=0<r||0<B?ss(t.left+F,t.top+l,Math.max(0,r-F),Math.max(0,B-l),As.TOP_LEFT):new Zn(t.left+F,t.top+l),this.topRightPaddingBox=0<n||0<s?ss(t.left+Math.min(a,t.width-C),t.top+l,a>t.width+C?0:Math.max(0,n-C),Math.max(0,s-l),As.TOP_RIGHT):new Zn(t.left+t.width-C,t.top+l),this.bottomRightPaddingBox=0<o||0<i?ss(t.left+Math.min(w,t.width-F),t.top+Math.min(g,t.height-u),Math.max(0,o-C),Math.max(0,i-u),As.BOTTOM_RIGHT):new Zn(t.left+t.width-C,t.top+t.height-u),this.bottomLeftPaddingBox=0<Q||0<c?ss(t.left+F,t.top+Math.min(U,t.height-u),Math.max(0,Q-F),Math.max(0,c-u),As.BOTTOM_LEFT):new Zn(t.left+F,t.top+t.height-u),this.topLeftContentBox=0<r||0<B?ss(t.left+F+A,t.top+l+h,Math.max(0,r-(F+A)),Math.max(0,B-(l+h)),As.TOP_LEFT):new Zn(t.left+F+A,t.top+l+h),this.topRightContentBox=0<n||0<s?ss(t.left+Math.min(a,t.width+F+A),t.top+l+h,a>t.width+F+A?0:n-F+A,s-(l+h),As.TOP_RIGHT):new Zn(t.left+t.width-(C+d),t.top+l+h),this.bottomRightContentBox=0<o||0<i?ss(t.left+Math.min(w,t.width-(F+A)),t.top+Math.min(g,t.height+l+h),Math.max(0,o-(C+d)),i-(u+f),As.BOTTOM_RIGHT):new Zn(t.left+t.width-(C+d),t.top+t.height-(u+f)),this.bottomLeftContentBox=0<Q||0<c?ss(t.left+F+A,t.top+U,Math.max(0,Q-(F+A)),c-(u+f),As.BOTTOM_LEFT):new Zn(t.left+F+A,t.top+t.height-(u+f))};(he=As=As||{})[he.TOP_LEFT=0]="TOP_LEFT",he[he.TOP_RIGHT=1]="TOP_RIGHT",he[he.BOTTOM_RIGHT=2]="BOTTOM_RIGHT",he[he.BOTTOM_LEFT=3]="BOTTOM_LEFT";function ts(A){return[A.topLeftBorderBox,A.topRightBorderBox,A.bottomRightBorderBox,A.bottomLeftBorderBox]}function rs(A){return[A.topLeftPaddingBox,A.topRightPaddingBox,A.bottomRightPaddingBox,A.bottomLeftPaddingBox]}function Bs(A){return 1===A.type}function ns(A,t){return A.length===t.length&&A.some(function(A,e){return A===t[e]})}var ss=function(A,e,t,r,B){var n=(Math.sqrt(2)-1)/3*4,s=t*n,o=r*n,i=A+t,Q=e+r;switch(B){case As.TOP_LEFT:return new jn(new Zn(A,Q),new Zn(A,Q-o),new Zn(i-s,e),new Zn(i,e));case As.TOP_RIGHT:return new jn(new Zn(A,e),new Zn(A+s,e),new Zn(i,Q-o),new Zn(i,Q));case As.BOTTOM_RIGHT:return new jn(new Zn(i,e),new Zn(i,e+o),new Zn(A+s,Q),new Zn(A,Q));default:As.BOTTOM_LEFT;return new jn(new Zn(i,Q),new Zn(i-s,Q),new Zn(A,e+o),new Zn(A,e))}},os=function(A,e,t){this.offsetX=A,this.offsetY=e,this.matrix=t,this.type=0,this.target=6},is=function(A,e){this.path=A,this.target=e,this.type=1},Qs=function(A){this.opacity=A,this.type=2,this.target=6},cs=function(A){this.element=A,this.inlineLevel=[],this.nonInlineLevel=[],this.negativeZIndex=[],this.zeroOrAutoZIndexOrTransformedOrOpacity=[],this.positiveZIndex=[],this.nonPositionedFloats=[],this.nonPositionedInlineLevel=[]},as=(gs.prototype.getEffects=function(e){for(var A=-1===[2,3].indexOf(this.container.styles.position),t=this.parent,r=this.effects.slice(0);t;){var B,n,s=t.effects.filter(function(A){return!Bs(A)});A||0!==t.container.styles.position||!t.parent?(r.unshift.apply(r,s),A=-1===[2,3].indexOf(t.container.styles.position),0!==t.container.styles.overflowX&&(B=ts(t.curves),n=rs(t.curves),ns(B,n)||r.unshift(new is(n,6)))):r.unshift.apply(r,s),t=t.parent}return r.filter(function(A){return Pt(A.target,e)})},gs);function gs(A,e){var t,r;this.container=A,this.parent=e,this.effects=[],this.curves=new es(this.container),this.container.styles.opacity<1&&this.effects.push(new Qs(this.container.styles.opacity)),null!==this.container.styles.transform&&(e=this.container.bounds.left+this.container.styles.transformOrigin[0].number,t=this.container.bounds.top+this.container.styles.transformOrigin[1].number,r=this.container.styles.transform,this.effects.push(new os(e,t,r))),0!==this.container.styles.overflowX&&(t=ts(this.curves),r=rs(this.curves),ns(t,r)?this.effects.push(new is(t,6)):(this.effects.push(new is(t,2)),this.effects.push(new is(r,4))))}function ws(A,e){switch(e){case 0:return Hs(A.topLeftBorderBox,A.topLeftPaddingBox,A.topRightBorderBox,A.topRightPaddingBox);case 1:return Hs(A.topRightBorderBox,A.topRightPaddingBox,A.bottomRightBorderBox,A.bottomRightPaddingBox);case 2:return Hs(A.bottomRightBorderBox,A.bottomRightPaddingBox,A.bottomLeftBorderBox,A.bottomLeftPaddingBox);default:return Hs(A.bottomLeftBorderBox,A.bottomLeftPaddingBox,A.topLeftBorderBox,A.topLeftPaddingBox)}}function Us(A){var e=A.bounds,A=A.styles;return e.add(A.borderLeftWidth,A.borderTopWidth,-(A.borderRightWidth+A.borderLeftWidth),-(A.borderTopWidth+A.borderBottomWidth))}function ls(A){var e=A.styles,t=A.bounds,r=Ue(e.paddingLeft,t.width),B=Ue(e.paddingRight,t.width),n=Ue(e.paddingTop,t.width),A=Ue(e.paddingBottom,t.width);return t.add(r+e.borderLeftWidth,n+e.borderTopWidth,-(e.borderRightWidth+e.borderLeftWidth+r+B),-(e.borderTopWidth+e.borderBottomWidth+n+A))}function Cs(A,e,t){var r=(B=Es(A.styles.backgroundOrigin,e),n=A,0===B?n.bounds:(2===B?ls:Us)(n)),B=(s=Es(A.styles.backgroundClip,e),o=A,0===s?o.bounds:(2===s?ls:Us)(o)),n=ps(Es(A.styles.backgroundSize,e),t,r),s=n[0],o=n[1],t=Be(Es(A.styles.backgroundPosition,e),r.width-s,r.height-o);return[Is(Es(A.styles.backgroundRepeat,e),t,n,r,B),Math.round(r.left+t[0]),Math.round(r.top+t[1]),s,o]}function us(A){return _A(A)&&A.value===Ve.AUTO}function Fs(A){return"number"==typeof A}var hs=function(Q,c,a,g){Q.container.elements.forEach(function(A){var e=Pt(A.flags,4),t=Pt(A.flags,2),r=new as(A,Q);Pt(A.styles.display,2048)&&g.push(r);var B,n,s,o,i=Pt(A.flags,8)?[]:g;e||t?(B=e||A.styles.isPositioned()?a:c,t=new cs(r),A.styles.isPositioned()||A.styles.opacity<1||A.styles.isTransformed()?(n=A.styles.zIndex.order)<0?(s=0,B.negativeZIndex.some(function(A,e){return n>A.element.container.styles.zIndex.order?(s=e,!1):0<s}),B.negativeZIndex.splice(s,0,t)):0<n?(o=0,B.positiveZIndex.some(function(A,e){return n>=A.element.container.styles.zIndex.order?(o=e+1,!1):0<o}),B.positiveZIndex.splice(o,0,t)):B.zeroOrAutoZIndexOrTransformedOrOpacity.push(t):(A.styles.isFloating()?B.nonPositionedFloats:B.nonPositionedInlineLevel).push(t),hs(r,t,e?t:a,i)):((A.styles.isInlineLevel()?c.inlineLevel:c.nonInlineLevel).push(r),hs(r,c,a,i)),Pt(A.flags,8)&&ds(A,i)})},ds=function(A,e){for(var t=A instanceof UB?A.start:1,r=A instanceof UB&&A.reversed,B=0;B<e.length;B++){var n=e[B];n.container instanceof aB&&"number"==typeof n.container.value&&0!==n.container.value&&(t=n.container.value),n.listValue=Fn(t,n.container.styles.listStyleType,!0),t+=r?-1:1}},fs=function(A,e){var t=[];return $n(A)?t.push(A.subdivide(.5,!1)):t.push(A),$n(e)?t.push(e.subdivide(.5,!0)):t.push(e),t},Hs=function(A,e,t,r){var B=[];return $n(A)?B.push(A.subdivide(.5,!1)):B.push(A),$n(t)?B.push(t.subdivide(.5,!0)):B.push(t),$n(r)?B.push(r.subdivide(.5,!0).reverse()):B.push(r),$n(e)?B.push(e.subdivide(.5,!1).reverse()):B.push(e),B},ps=function(A,e,t){var r=e[0],B=e[1],n=e[2],s=A[0],o=A[1];if(!s)return[0,0];if(te(s)&&o&&te(o))return[Ue(s,t.width),Ue(o,t.height)];var i=Fs(n);if(_A(s)&&(s.value===Ve.CONTAIN||s.value===Ve.COVER))return Fs(n)?t.width/t.height<n!=(s.value===Ve.COVER)?[t.width,t.width/n]:[t.height*n,t.height]:[t.width,t.height];var Q=Fs(r),e=Fs(B),A=Q||e;if(us(s)&&(!o||us(o)))return Q&&e?[r,B]:i||A?A&&i?[Q?r:B*n,e?B:r/n]:[Q?r:t.width,e?B:t.height]:[t.width,t.height];if(i){var c=0,a=0;return te(s)?c=Ue(s,t.width):te(o)&&(a=Ue(o,t.height)),us(s)?c=a*n:o&&!us(o)||(a=c/n),[c,a]}c=null,a=null;if(te(s)?c=Ue(s,t.width):o&&te(o)&&(a=Ue(o,t.height)),null!==(c=null!==(a=null!==c&&(!o||us(o))?Q&&e?c/r*B:t.height:a)&&us(s)?Q&&e?a/B*r:t.width:c)&&null!==a)return[c,a];throw new Error("Unable to calculate background-size for element")},Es=function(A,e){e=A[e];return void 0===e?A[0]:e},Is=function(A,e,t,r,B){var n=e[0],s=e[1],o=t[0],i=t[1];switch(A){case 2:return[new Zn(Math.round(r.left),Math.round(r.top+s)),new Zn(Math.round(r.left+r.width),Math.round(r.top+s)),new Zn(Math.round(r.left+r.width),Math.round(i+r.top+s)),new Zn(Math.round(r.left),Math.round(i+r.top+s))];case 3:return[new Zn(Math.round(r.left+n),Math.round(r.top)),new Zn(Math.round(r.left+n+o),Math.round(r.top)),new Zn(Math.round(r.left+n+o),Math.round(r.height+r.top)),new Zn(Math.round(r.left+n),Math.round(r.height+r.top))];case 1:return[new Zn(Math.round(r.left+n),Math.round(r.top+s)),new Zn(Math.round(r.left+n+o),Math.round(r.top+s)),new Zn(Math.round(r.left+n+o),Math.round(r.top+s+i)),new Zn(Math.round(r.left+n),Math.round(r.top+s+i))];default:return[new Zn(Math.round(B.left),Math.round(B.top)),new Zn(Math.round(B.left+B.width),Math.round(B.top)),new Zn(Math.round(B.left+B.width),Math.round(B.height+B.top)),new Zn(Math.round(B.left),Math.round(B.height+B.top))]}},ys="Hidden Text",Ks=(ms.prototype.parseMetrics=function(A,e){var t=this._document.createElement("div"),r=this._document.createElement("img"),B=this._document.createElement("span"),n=this._document.body;t.style.visibility="hidden",t.style.fontFamily=A,t.style.fontSize=e,t.style.margin="0",t.style.padding="0",t.style.whiteSpace="nowrap",n.appendChild(t),r.src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",r.width=1,r.height=1,r.style.margin="0",r.style.padding="0",r.style.verticalAlign="baseline",B.style.fontFamily=A,B.style.fontSize=e,B.style.margin="0",B.style.padding="0",B.appendChild(this._document.createTextNode(ys)),t.appendChild(B),t.appendChild(r);e=r.offsetTop-B.offsetTop+2;t.removeChild(B),t.appendChild(this._document.createTextNode(ys)),t.style.lineHeight="normal",r.style.verticalAlign="super";r=r.offsetTop-t.offsetTop+2;return n.removeChild(t),{baseline:e,middle:r}},ms.prototype.getMetrics=function(A,e){var t=A+" "+e;return void 0===this._data[t]&&(this._data[t]=this.parseMetrics(A,e)),this._data[t]},ms);function ms(A){this._data={},this._document=A}var Ls,he=function(A,e){this.context=A,this.options=e},bs=(A(Ds,Ls=he),Ds.prototype.applyEffects=function(A){for(var e=this;this._activeEffects.length;)this.popEffect();A.forEach(function(A){return e.applyEffect(A)})},Ds.prototype.applyEffect=function(A){this.ctx.save(),2===A.type&&(this.ctx.globalAlpha=A.opacity),0===A.type&&(this.ctx.translate(A.offsetX,A.offsetY),this.ctx.transform(A.matrix[0],A.matrix[1],A.matrix[2],A.matrix[3],A.matrix[4],A.matrix[5]),this.ctx.translate(-A.offsetX,-A.offsetY)),Bs(A)&&(this.path(A.path),this.ctx.clip()),this._activeEffects.push(A)},Ds.prototype.popEffect=function(){this._activeEffects.pop(),this.ctx.restore()},Ds.prototype.renderStack=function(e){return a(this,void 0,void 0,function(){return H(this,function(A){switch(A.label){case 0:return e.element.container.styles.isVisible()?[4,this.renderStackContent(e)]:[3,2];case 1:A.sent(),A.label=2;case 2:return[2]}})})},Ds.prototype.renderNode=function(e){return a(this,void 0,void 0,function(){return H(this,function(A){switch(A.label){case 0:return Pt(e.container.flags,16),e.container.styles.isVisible()?[4,this.renderNodeBackgroundAndBorders(e)]:[3,3];case 1:return A.sent(),[4,this.renderNodeContent(e)];case 2:A.sent(),A.label=3;case 3:return[2]}})})},Ds.prototype.renderTextWithLetterSpacing=function(t,A,r){var B=this;0===A?this.ctx.fillText(t.text,t.bounds.left,t.bounds.top+r):Zr(t.text).reduce(function(A,e){return B.ctx.fillText(e,A,t.bounds.top+r),A+B.ctx.measureText(e).width},t.bounds.left)},Ds.prototype.createFontStyle=function(A){var e=A.fontVariant.filter(function(A){return"normal"===A||"small-caps"===A}).join(""),t=Gs(A.fontFamily).join(", "),r=WA(A.fontSize)?""+A.fontSize.number+A.fontSize.unit:A.fontSize.number+"px";return[[A.fontStyle,e,A.fontWeight,r,t].join(" "),t,r]},Ds.prototype.renderTextNode=function(i,Q){return a(this,void 0,void 0,function(){var e,t,r,B,n,s,o=this;return H(this,function(A){return r=this.createFontStyle(Q),e=r[0],t=r[1],r=r[2],this.ctx.font=e,this.ctx.direction=1===Q.direction?"rtl":"ltr",this.ctx.textAlign="left",this.ctx.textBaseline="alphabetic",r=this.fontMetrics.getMetrics(t,r),B=r.baseline,n=r.middle,s=Q.paintOrder,i.textBounds.forEach(function(t){s.forEach(function(A){switch(A){case 0:o.ctx.fillStyle=ie(Q.color),o.renderTextWithLetterSpacing(t,Q.letterSpacing,B);var e=Q.textShadow;e.length&&t.text.trim().length&&(e.slice(0).reverse().forEach(function(A){o.ctx.shadowColor=ie(A.color),o.ctx.shadowOffsetX=A.offsetX.number*o.options.scale,o.ctx.shadowOffsetY=A.offsetY.number*o.options.scale,o.ctx.shadowBlur=A.blur.number,o.renderTextWithLetterSpacing(t,Q.letterSpacing,B)}),o.ctx.shadowColor="",o.ctx.shadowOffsetX=0,o.ctx.shadowOffsetY=0,o.ctx.shadowBlur=0),Q.textDecorationLine.length&&(o.ctx.fillStyle=ie(Q.textDecorationColor||Q.color),Q.textDecorationLine.forEach(function(A){switch(A){case 1:o.ctx.fillRect(t.bounds.left,Math.round(t.bounds.top+B),t.bounds.width,1);break;case 2:o.ctx.fillRect(t.bounds.left,Math.round(t.bounds.top),t.bounds.width,1);break;case 3:o.ctx.fillRect(t.bounds.left,Math.ceil(t.bounds.top+n),t.bounds.width,1)}}));break;case 1:Q.webkitTextStrokeWidth&&t.text.trim().length&&(o.ctx.strokeStyle=ie(Q.webkitTextStrokeColor),o.ctx.lineWidth=Q.webkitTextStrokeWidth,o.ctx.lineJoin=window.chrome?"miter":"round",o.ctx.strokeText(t.text,t.bounds.left,t.bounds.top+B)),o.ctx.strokeStyle="",o.ctx.lineWidth=0,o.ctx.lineJoin="miter"}})}),[2]})})},Ds.prototype.renderReplacedElement=function(A,e,t){var r;t&&0<A.intrinsicWidth&&0<A.intrinsicHeight&&(r=ls(A),e=rs(e),this.path(e),this.ctx.save(),this.ctx.clip(),this.ctx.drawImage(t,0,0,A.intrinsicWidth,A.intrinsicHeight,r.left,r.top,r.width,r.height),this.ctx.restore())},Ds.prototype.renderNodeContent=function(w){return a(this,void 0,void 0,function(){var e,t,r,B,n,s,o,i,Q,c,a,g;return H(this,function(A){switch(A.label){case 0:this.applyEffects(w.getEffects(4)),e=w.container,t=w.curves,r=e.styles,B=0,n=e.textNodes,A.label=1;case 1:return B<n.length?(s=n[B],[4,this.renderTextNode(s,r)]):[3,4];case 2:A.sent(),A.label=3;case 3:return B++,[3,1];case 4:if(!(e instanceof tB))return[3,8];A.label=5;case 5:return A.trys.push([5,7,,8]),[4,this.context.cache.match(e.src)];case 6:return Q=A.sent(),this.renderReplacedElement(e,t,Q),[3,8];case 7:return A.sent(),this.context.logger.error("Error loading image "+e.src),[3,8];case 8:if(e instanceof nB&&this.renderReplacedElement(e,t,e.canvas),!(e instanceof iB))return[3,12];A.label=9;case 9:return A.trys.push([9,11,,12]),[4,this.context.cache.match(e.svg)];case 10:return Q=A.sent(),this.renderReplacedElement(e,t,Q),[3,12];case 11:return A.sent(),this.context.logger.error("Error loading svg "+e.svg.substring(0,255)),[3,12];case 12:return e instanceof vB&&e.tree?[4,new Ds(this.context,{scale:this.options.scale,backgroundColor:e.backgroundColor,x:0,y:0,width:e.width,height:e.height}).render(e.tree)]:[3,14];case 13:s=A.sent(),e.width&&e.height&&this.ctx.drawImage(s,0,0,e.width,e.height,e.bounds.left,e.bounds.top,e.bounds.width,e.bounds.height),A.label=14;case 14:if(e instanceof pB&&(i=Math.min(e.bounds.width,e.bounds.height),e.type===hB?e.checked&&(this.ctx.save(),this.path([new Zn(e.bounds.left+.39363*i,e.bounds.top+.79*i),new Zn(e.bounds.left+.16*i,e.bounds.top+.5549*i),new Zn(e.bounds.left+.27347*i,e.bounds.top+.44071*i),new Zn(e.bounds.left+.39694*i,e.bounds.top+.5649*i),new Zn(e.bounds.left+.72983*i,e.bounds.top+.23*i),new Zn(e.bounds.left+.84*i,e.bounds.top+.34085*i),new Zn(e.bounds.left+.39363*i,e.bounds.top+.79*i)]),this.ctx.fillStyle=ie(HB),this.ctx.fill(),this.ctx.restore()):e.type===dB&&e.checked&&(this.ctx.save(),this.ctx.beginPath(),this.ctx.arc(e.bounds.left+i/2,e.bounds.top+i/2,i/4,0,2*Math.PI,!0),this.ctx.fillStyle=ie(HB),this.ctx.fill(),this.ctx.restore())),xs(e)&&e.value.length){switch(c=this.createFontStyle(r),a=c[0],i=c[1],c=this.fontMetrics.getMetrics(a,i).baseline,this.ctx.font=a,this.ctx.fillStyle=ie(r.color),this.ctx.textBaseline="alphabetic",this.ctx.textAlign=Ss(e.styles.textAlign),g=ls(e),o=0,e.styles.textAlign){case 1:o+=g.width/2;break;case 2:o+=g.width}i=g.add(o,0,0,-g.height/2+1),this.ctx.save(),this.path([new Zn(g.left,g.top),new Zn(g.left+g.width,g.top),new Zn(g.left+g.width,g.top+g.height),new Zn(g.left,g.top+g.height)]),this.ctx.clip(),this.renderTextWithLetterSpacing(new Jr(e.value,i),r.letterSpacing,c),this.ctx.restore(),this.ctx.textBaseline="alphabetic",this.ctx.textAlign="left"}if(!Pt(e.styles.display,2048))return[3,20];if(null===e.styles.listStyleImage)return[3,19];if(0!==(c=e.styles.listStyleImage).type)return[3,18];Q=void 0,c=c.url,A.label=15;case 15:return A.trys.push([15,17,,18]),[4,this.context.cache.match(c)];case 16:return Q=A.sent(),this.ctx.drawImage(Q,e.bounds.left-(Q.width+10),e.bounds.top),[3,18];case 17:return A.sent(),this.context.logger.error("Error loading list-style-image "+c),[3,18];case 18:return[3,20];case 19:w.listValue&&-1!==e.styles.listStyleType&&(a=this.createFontStyle(r)[0],this.ctx.font=a,this.ctx.fillStyle=ie(r.color),this.ctx.textBaseline="middle",this.ctx.textAlign="right",g=new d(e.bounds.left,e.bounds.top+Ue(e.styles.paddingTop,e.bounds.width),e.bounds.width,Ye(r.lineHeight,r.fontSize.number)/2+1),this.renderTextWithLetterSpacing(new Jr(w.listValue,g),r.letterSpacing,Ye(r.lineHeight,r.fontSize.number)/2+2),this.ctx.textBaseline="bottom",this.ctx.textAlign="left"),A.label=20;case 20:return[2]}})})},Ds.prototype.renderStackContent=function(C){return a(this,void 0,void 0,function(){var e,t,r,B,n,s,o,i,Q,c,a,g,w,U,l;return H(this,function(A){switch(A.label){case 0:return Pt(C.element.container.flags,16),[4,this.renderNodeBackgroundAndBorders(C.element)];case 1:A.sent(),e=0,t=C.negativeZIndex,A.label=2;case 2:return e<t.length?(l=t[e],[4,this.renderStack(l)]):[3,5];case 3:A.sent(),A.label=4;case 4:return e++,[3,2];case 5:return[4,this.renderNodeContent(C.element)];case 6:A.sent(),r=0,B=C.nonInlineLevel,A.label=7;case 7:return r<B.length?(l=B[r],[4,this.renderNode(l)]):[3,10];case 8:A.sent(),A.label=9;case 9:return r++,[3,7];case 10:n=0,s=C.nonPositionedFloats,A.label=11;case 11:return n<s.length?(l=s[n],[4,this.renderStack(l)]):[3,14];case 12:A.sent(),A.label=13;case 13:return n++,[3,11];case 14:o=0,i=C.nonPositionedInlineLevel,A.label=15;case 15:return o<i.length?(l=i[o],[4,this.renderStack(l)]):[3,18];case 16:A.sent(),A.label=17;case 17:return o++,[3,15];case 18:Q=0,c=C.inlineLevel,A.label=19;case 19:return Q<c.length?(l=c[Q],[4,this.renderNode(l)]):[3,22];case 20:A.sent(),A.label=21;case 21:return Q++,[3,19];case 22:a=0,g=C.zeroOrAutoZIndexOrTransformedOrOpacity,A.label=23;case 23:return a<g.length?(l=g[a],[4,this.renderStack(l)]):[3,26];case 24:A.sent(),A.label=25;case 25:return a++,[3,23];case 26:w=0,U=C.positiveZIndex,A.label=27;case 27:return w<U.length?(l=U[w],[4,this.renderStack(l)]):[3,30];case 28:A.sent(),A.label=29;case 29:return w++,[3,27];case 30:return[2]}})})},Ds.prototype.mask=function(A){this.ctx.beginPath(),this.ctx.moveTo(0,0),this.ctx.lineTo(this.canvas.width,0),this.ctx.lineTo(this.canvas.width,this.canvas.height),this.ctx.lineTo(0,this.canvas.height),this.ctx.lineTo(0,0),this.formatPath(A.slice(0).reverse()),this.ctx.closePath()},Ds.prototype.path=function(A){this.ctx.beginPath(),this.formatPath(A),this.ctx.closePath()},Ds.prototype.formatPath=function(A){var r=this;A.forEach(function(A,e){var t=$n(A)?A.start:A;0===e?r.ctx.moveTo(t.x,t.y):r.ctx.lineTo(t.x,t.y),$n(A)&&r.ctx.bezierCurveTo(A.startControl.x,A.startControl.y,A.endControl.x,A.endControl.y,A.end.x,A.end.y)})},Ds.prototype.renderRepeat=function(A,e,t,r){this.path(A),this.ctx.fillStyle=e,this.ctx.translate(t,r),this.ctx.fill(),this.ctx.translate(-t,-r)},Ds.prototype.resizeImage=function(A,e,t){if(A.width===e&&A.height===t)return A;var r=(null!==(r=this.canvas.ownerDocument)&&void 0!==r?r:document).createElement("canvas");return r.width=Math.max(1,e),r.height=Math.max(1,t),r.getContext("2d").drawImage(A,0,0,A.width,A.height,0,0,e,t),r},Ds.prototype.renderBackgroundImage=function(f){return a(this,void 0,void 0,function(){var h,e,d,t,r,B;return H(this,function(A){switch(A.label){case 0:h=f.styles.backgroundImage.length-1,e=function(e){var t,r,B,n,s,o,i,Q,c,a,g,w,U,l,C,u,F;return H(this,function(A){switch(A.label){case 0:if(0!==e.type)return[3,5];t=void 0,r=e.url,A.label=1;case 1:return A.trys.push([1,3,,4]),[4,d.context.cache.match(r)];case 2:return t=A.sent(),[3,4];case 3:return A.sent(),d.context.logger.error("Error loading background-image "+r),[3,4];case 4:return t&&(B=Cs(f,h,[t.width,t.height,t.width/t.height]),o=B[0],g=B[1],w=B[2],c=B[3],a=B[4],s=d.ctx.createPattern(d.resizeImage(t,c,a),"repeat"),d.renderRepeat(o,s,g,w)),[3,6];case 5:1===e.type?(F=Cs(f,h,[null,null,null]),o=F[0],g=F[1],w=F[2],c=F[3],a=F[4],C=Ee(e.angle,c,a),l=C[0],B=C[1],i=C[2],u=C[3],Q=C[4],(F=document.createElement("canvas")).width=c,F.height=a,C=F.getContext("2d"),n=C.createLinearGradient(B,u,i,Q),pe(e.stops,l).forEach(function(A){return n.addColorStop(A.stop,ie(A.color))}),C.fillStyle=n,C.fillRect(0,0,c,a),0<c&&0<a&&(s=d.ctx.createPattern(F,"repeat"),d.renderRepeat(o,s,g,w))):2===e.type&&(u=Cs(f,h,[null,null,null]),o=u[0],i=u[1],Q=u[2],c=u[3],a=u[4],l=0===e.position.length?[ge]:e.position,g=Ue(l[0],c),w=Ue(l[l.length-1],a),C=function(A,e,t,r,B){var n,s,o,i,Q=0,c=0;switch(A.size){case 0:0===A.shape?Q=c=Math.min(Math.abs(e),Math.abs(e-r),Math.abs(t),Math.abs(t-B)):1===A.shape&&(Q=Math.min(Math.abs(e),Math.abs(e-r)),c=Math.min(Math.abs(t),Math.abs(t-B)));break;case 2:0===A.shape?Q=c=Math.min(Ie(e,t),Ie(e,t-B),Ie(e-r,t),Ie(e-r,t-B)):1===A.shape&&(n=Math.min(Math.abs(t),Math.abs(t-B))/Math.min(Math.abs(e),Math.abs(e-r)),o=(s=ye(r,B,e,t,!0))[0],i=s[1],c=n*(Q=Ie(o-e,(i-t)/n)));break;case 1:0===A.shape?Q=c=Math.max(Math.abs(e),Math.abs(e-r),Math.abs(t),Math.abs(t-B)):1===A.shape&&(Q=Math.max(Math.abs(e),Math.abs(e-r)),c=Math.max(Math.abs(t),Math.abs(t-B)));break;case 3:0===A.shape?Q=c=Math.max(Ie(e,t),Ie(e,t-B),Ie(e-r,t),Ie(e-r,t-B)):1===A.shape&&(n=Math.max(Math.abs(t),Math.abs(t-B))/Math.max(Math.abs(e),Math.abs(e-r)),o=(s=ye(r,B,e,t,!1))[0],i=s[1],c=n*(Q=Ie(o-e,(i-t)/n)))}return Array.isArray(A.size)&&(Q=Ue(A.size[0],r),c=2===A.size.length?Ue(A.size[1],B):Q),[Q,c]}(e,g,w,c,a),F=C[0],u=C[1],0<F&&0<u&&(U=d.ctx.createRadialGradient(i+g,Q+w,0,i+g,Q+w,F),pe(e.stops,2*F).forEach(function(A){return U.addColorStop(A.stop,ie(A.color))}),d.path(o),d.ctx.fillStyle=U,F!==u?(l=f.bounds.left+.5*f.bounds.width,C=f.bounds.top+.5*f.bounds.height,F=1/(u=u/F),d.ctx.save(),d.ctx.translate(l,C),d.ctx.transform(1,0,0,u,0,0),d.ctx.translate(-l,-C),d.ctx.fillRect(i,F*(Q-C)+C,c,a*F),d.ctx.restore()):d.ctx.fill())),A.label=6;case 6:return h--,[2]}})},d=this,t=0,r=f.styles.backgroundImage.slice(0).reverse(),A.label=1;case 1:return t<r.length?(B=r[t],[5,e(B)]):[3,4];case 2:A.sent(),A.label=3;case 3:return t++,[3,1];case 4:return[2]}})})},Ds.prototype.renderSolidBorder=function(e,t,r){return a(this,void 0,void 0,function(){return H(this,function(A){return this.path(ws(r,t)),this.ctx.fillStyle=ie(e),this.ctx.fill(),[2]})})},Ds.prototype.renderDoubleBorder=function(t,r,B,n){return a(this,void 0,void 0,function(){var e;return H(this,function(A){switch(A.label){case 0:return r<3?[4,this.renderSolidBorder(t,B,n)]:[3,2];case 1:return A.sent(),[2];case 2:return e=function(A,e){switch(e){case 0:return Hs(A.topLeftBorderBox,A.topLeftBorderDoubleOuterBox,A.topRightBorderBox,A.topRightBorderDoubleOuterBox);case 1:return Hs(A.topRightBorderBox,A.topRightBorderDoubleOuterBox,A.bottomRightBorderBox,A.bottomRightBorderDoubleOuterBox);case 2:return Hs(A.bottomRightBorderBox,A.bottomRightBorderDoubleOuterBox,A.bottomLeftBorderBox,A.bottomLeftBorderDoubleOuterBox);default:return Hs(A.bottomLeftBorderBox,A.bottomLeftBorderDoubleOuterBox,A.topLeftBorderBox,A.topLeftBorderDoubleOuterBox)}}(n,B),this.path(e),this.ctx.fillStyle=ie(t),this.ctx.fill(),e=function(A,e){switch(e){case 0:return Hs(A.topLeftBorderDoubleInnerBox,A.topLeftPaddingBox,A.topRightBorderDoubleInnerBox,A.topRightPaddingBox);case 1:return Hs(A.topRightBorderDoubleInnerBox,A.topRightPaddingBox,A.bottomRightBorderDoubleInnerBox,A.bottomRightPaddingBox);case 2:return Hs(A.bottomRightBorderDoubleInnerBox,A.bottomRightPaddingBox,A.bottomLeftBorderDoubleInnerBox,A.bottomLeftPaddingBox);default:return Hs(A.bottomLeftBorderDoubleInnerBox,A.bottomLeftPaddingBox,A.topLeftBorderDoubleInnerBox,A.topLeftPaddingBox)}}(n,B),this.path(e),this.ctx.fill(),[2]}})})},Ds.prototype.renderNodeBackgroundAndBorders=function(c){return a(this,void 0,void 0,function(){var e,t,r,B,n,s,o,i,Q=this;return H(this,function(A){switch(A.label){case 0:return(this.applyEffects(c.getEffects(2)),e=c.container.styles,t=!oe(e.backgroundColor)||e.backgroundImage.length,r=[{style:e.borderTopStyle,color:e.borderTopColor,width:e.borderTopWidth},{style:e.borderRightStyle,color:e.borderRightColor,width:e.borderRightWidth},{style:e.borderBottomStyle,color:e.borderBottomColor,width:e.borderBottomWidth},{style:e.borderLeftStyle,color:e.borderLeftColor,width:e.borderLeftWidth}],B=Ms(Es(e.backgroundClip,0),c.curves),t||e.boxShadow.length)?(this.ctx.save(),this.path(B),this.ctx.clip(),oe(e.backgroundColor)||(this.ctx.fillStyle=ie(e.backgroundColor),this.ctx.fill()),[4,this.renderBackgroundImage(c.container)]):[3,2];case 1:A.sent(),this.ctx.restore(),e.boxShadow.slice(0).reverse().forEach(function(A){Q.ctx.save();var t,r,B,n,e=ts(c.curves),s=A.inset?0:1e4,o=(t=-s+(A.inset?1:-1)*A.spread.number,r=(A.inset?1:-1)*A.spread.number,B=A.spread.number*(A.inset?-2:2),n=A.spread.number*(A.inset?-2:2),e.map(function(A,e){switch(e){case 0:return A.add(t,r);case 1:return A.add(t+B,r);case 2:return A.add(t+B,r+n);case 3:return A.add(t,r+n)}return A}));A.inset?(Q.path(e),Q.ctx.clip(),Q.mask(o)):(Q.mask(e),Q.ctx.clip(),Q.path(o)),Q.ctx.shadowOffsetX=A.offsetX.number+s,Q.ctx.shadowOffsetY=A.offsetY.number,Q.ctx.shadowColor=ie(A.color),Q.ctx.shadowBlur=A.blur.number,Q.ctx.fillStyle=A.inset?ie(A.color):"rgba(0,0,0,1)",Q.ctx.fill(),Q.ctx.restore()}),A.label=2;case 2:s=n=0,o=r,A.label=3;case 3:return s<o.length?0!==(i=o[s]).style&&!oe(i.color)&&0<i.width?2!==i.style?[3,5]:[4,this.renderDashedDottedBorder(i.color,i.width,n,c.curves,2)]:[3,11]:[3,13];case 4:return A.sent(),[3,11];case 5:return 3!==i.style?[3,7]:[4,this.renderDashedDottedBorder(i.color,i.width,n,c.curves,3)];case 6:return A.sent(),[3,11];case 7:return 4!==i.style?[3,9]:[4,this.renderDoubleBorder(i.color,i.width,n,c.curves)];case 8:return A.sent(),[3,11];case 9:return[4,this.renderSolidBorder(i.color,n,c.curves)];case 10:A.sent(),A.label=11;case 11:n++,A.label=12;case 12:return s++,[3,3];case 13:return[2]}})})},Ds.prototype.renderDashedDottedBorder=function(g,w,U,l,C){return a(this,void 0,void 0,function(){var e,t,r,B,n,s,o,i,Q,c,a;return H(this,function(A){return this.ctx.save(),Q=function(A,e){switch(e){case 0:return fs(A.topLeftBorderStroke,A.topRightBorderStroke);case 1:return fs(A.topRightBorderStroke,A.bottomRightBorderStroke);case 2:return fs(A.bottomRightBorderStroke,A.bottomLeftBorderStroke);default:return fs(A.bottomLeftBorderStroke,A.topLeftBorderStroke)}}(l,U),e=ws(l,U),2===C&&(this.path(e),this.ctx.clip()),s=$n(e[0])?(t=e[0].start.x,e[0].start.y):(t=e[0].x,e[0].y),o=$n(e[1])?(r=e[1].end.x,e[1].end.y):(r=e[1].x,e[1].y),B=0===U||2===U?Math.abs(t-r):Math.abs(s-o),this.ctx.beginPath(),3===C?this.formatPath(Q):this.formatPath(e.slice(0,2)),n=w<3?3*w:2*w,s=w<3?2*w:w,3===C&&(s=n=w),o=!0,B<=2*n?o=!1:B<=2*n+s?(n*=i=B/(2*n+s),s*=i):(Q=Math.floor((B+s)/(n+s)),i=(B-Q*n)/(Q-1),s=(Q=(B-(Q+1)*n)/Q)<=0||Math.abs(s-i)<Math.abs(s-Q)?i:Q),o&&(3===C?this.ctx.setLineDash([0,n+s]):this.ctx.setLineDash([n,s])),3===C?(this.ctx.lineCap="round",this.ctx.lineWidth=w):this.ctx.lineWidth=2*w+1.1,this.ctx.strokeStyle=ie(g),this.ctx.stroke(),this.ctx.setLineDash([]),2===C&&($n(e[0])&&(c=e[3],a=e[0],this.ctx.beginPath(),this.formatPath([new Zn(c.end.x,c.end.y),new Zn(a.start.x,a.start.y)]),this.ctx.stroke()),$n(e[1])&&(c=e[1],a=e[2],this.ctx.beginPath(),this.formatPath([new Zn(c.end.x,c.end.y),new Zn(a.start.x,a.start.y)]),this.ctx.stroke())),this.ctx.restore(),[2]})})},Ds.prototype.render=function(B){return a(this,void 0,void 0,function(){return H(this,function(A){switch(A.label){case 0:return this.options.backgroundColor&&(this.ctx.fillStyle=ie(this.options.backgroundColor),this.ctx.fillRect(this.options.x,this.options.y,this.options.width,this.options.height)),t=new as(e=B,null),r=new cs(t),hs(t,r,r,e=[]),ds(t.container,e),[4,this.renderStack(r)];case 1:return A.sent(),this.applyEffects([]),[2,this.canvas]}var e,t,r})})},Ds);function Ds(A,e){A=Ls.call(this,A,e)||this;return A._activeEffects=[],A.canvas=e.canvas||document.createElement("canvas"),A.ctx=A.canvas.getContext("2d"),e.canvas||(A.canvas.width=Math.floor(e.width*e.scale),A.canvas.height=Math.floor(e.height*e.scale),A.canvas.style.width=e.width+"px",A.canvas.style.height=e.height+"px"),A.fontMetrics=new Ks(document),A.ctx.scale(A.options.scale,A.options.scale),A.ctx.translate(-e.x,-e.y),A.ctx.textBaseline="bottom",A._activeEffects=[],A.context.logger.debug("Canvas renderer initialized ("+e.width+"x"+e.height+") with scale "+e.scale),A}var vs,xs=function(A){return A instanceof LB||(A instanceof yB||A instanceof pB&&A.type!==dB&&A.type!==hB)},Ms=function(A,e){switch(A){case 0:return ts(e);case 2:return[e.topLeftContentBox,e.topRightContentBox,e.bottomRightContentBox,e.bottomLeftContentBox];default:return rs(e)}},Ss=function(A){switch(A){case 1:return"center";case 2:return"right";default:return"left"}},Ts=["-apple-system","system-ui"],Gs=function(A){return/iPhone OS 15_(0|1)/.test(window.navigator.userAgent)?A.filter(function(A){return-1===Ts.indexOf(A)}):A},Os=(A(Vs,vs=he),Vs.prototype.render=function(t){return a(this,void 0,void 0,function(){var e;return H(this,function(A){switch(A.label){case 0:return e=Nr(this.options.width*this.options.scale,this.options.height*this.options.scale,this.options.scale,this.options.scale,t),[4,ks(e)];case 1:return e=A.sent(),this.options.backgroundColor&&(this.ctx.fillStyle=ie(this.options.backgroundColor),this.ctx.fillRect(0,0,this.options.width*this.options.scale,this.options.height*this.options.scale)),this.ctx.drawImage(e,-this.options.x*this.options.scale,-this.options.y*this.options.scale),[2,this.canvas]}})})},Vs);function Vs(A,e){A=vs.call(this,A,e)||this;return A.canvas=e.canvas||document.createElement("canvas"),A.ctx=A.canvas.getContext("2d"),A.options=e,A.canvas.width=Math.floor(e.width*e.scale),A.canvas.height=Math.floor(e.height*e.scale),A.canvas.style.width=e.width+"px",A.canvas.style.height=e.height+"px",A.ctx.scale(A.options.scale,A.options.scale),A.ctx.translate(-e.x,-e.y),A.context.logger.debug("EXPERIMENTAL ForeignObject renderer initialized ("+e.width+"x"+e.height+" at "+e.x+","+e.y+") with scale "+e.scale),A}var ks=function(r){return new Promise(function(A,e){var t=new Image;t.onload=function(){A(t)},t.onerror=e,t.src="data:image/svg+xml;charset=utf-8,"+encodeURIComponent((new XMLSerializer).serializeToString(r))})},Rs=(Ns.prototype.debug=function(){for(var A=[],e=0;e<arguments.length;e++)A[e]=arguments[e];this.enabled&&("undefined"!=typeof window&&window.console&&"function"==typeof console.debug?console.debug.apply(console,t([this.id,this.getTime()+"ms"],A)):this.info.apply(this,A))},Ns.prototype.getTime=function(){return Date.now()-this.start},Ns.prototype.info=function(){for(var A=[],e=0;e<arguments.length;e++)A[e]=arguments[e];this.enabled&&"undefined"!=typeof window&&window.console&&"function"==typeof console.info&&console.info.apply(console,t([this.id,this.getTime()+"ms"],A))},Ns.prototype.warn=function(){for(var A=[],e=0;e<arguments.length;e++)A[e]=arguments[e];this.enabled&&("undefined"!=typeof window&&window.console&&"function"==typeof console.warn?console.warn.apply(console,t([this.id,this.getTime()+"ms"],A)):this.info.apply(this,A))},Ns.prototype.error=function(){for(var A=[],e=0;e<arguments.length;e++)A[e]=arguments[e];this.enabled&&("undefined"!=typeof window&&window.console&&"function"==typeof console.error?console.error.apply(console,t([this.id,this.getTime()+"ms"],A)):this.info.apply(this,A))},Ns.instances={},Ns);function Ns(A){var e=A.id,A=A.enabled;this.id=e,this.enabled=A,this.start=Date.now()}var Ps=(Xs.instanceCount=1,Xs);function Xs(A,e){this.windowBounds=e,this.instanceName="#"+Xs.instanceCount++,this.logger=new Rs({id:this.instanceName,enabled:A.logging}),this.cache=null!==(e=A.cache)&&void 0!==e?e:new On(this,A)}"undefined"!=typeof window&&Tn.setContext(window);var Js=function(u,F){return a(void 0,void 0,void 0,function(){var e,t,r,B,n,s,o,i,Q,c,a,g,w,U,l,C;return H(this,function(A){switch(A.label){case 0:if(!u||"object"!=typeof u)return[2,Promise.reject("Invalid element provided as first argument")];if(!(e=u.ownerDocument))throw new Error("Element is not attached to a Document");if(!(t=e.defaultView))throw new Error("Document is not attached to a Window");return w={allowTaint:null!==(U=F.allowTaint)&&void 0!==U&&U,imageTimeout:null!==(c=F.imageTimeout)&&void 0!==c?c:15e3,proxy:F.proxy,useCORS:null!==(a=F.useCORS)&&void 0!==a&&a},U=h({logging:null===(g=F.logging)||void 0===g||g,cache:F.cache},w),c={windowWidth:null!==(c=F.windowWidth)&&void 0!==c?c:t.innerWidth,windowHeight:null!==(a=F.windowHeight)&&void 0!==a?a:t.innerHeight,scrollX:null!==(g=F.scrollX)&&void 0!==g?g:t.pageXOffset,scrollY:null!==(w=F.scrollY)&&void 0!==w?w:t.pageYOffset},a=new d(c.scrollX,c.scrollY,c.windowWidth,c.windowHeight),g=new Ps(U,a),c=null!==(w=F.foreignObjectRendering)&&void 0!==w&&w,w={allowTaint:null!==(U=F.allowTaint)&&void 0!==U&&U,onclone:F.onclone,ignoreElements:F.ignoreElements,inlineImages:c,copyStyles:c},g.logger.debug("Starting document clone with size "+a.width+"x"+a.height+" scrolled to "+-a.left+","+-a.top),U=new dn(g,u,w),(w=U.clonedReferenceElement)?[4,U.toIFrame(e,a)]:[2,Promise.reject("Unable to find element in cloned iframe")];case 1:return(r=A.sent(),l=jB(w)||"HTML"===w.tagName?function(A){var e=A.body,t=A.documentElement;if(!e||!t)throw new Error("Unable to get document size");A=Math.max(Math.max(e.scrollWidth,t.scrollWidth),Math.max(e.offsetWidth,t.offsetWidth),Math.max(e.clientWidth,t.clientWidth)),t=Math.max(Math.max(e.scrollHeight,t.scrollHeight),Math.max(e.offsetHeight,t.offsetHeight),Math.max(e.clientHeight,t.clientHeight));return new d(0,0,A,t)}(w.ownerDocument):f(g,w),B=l.width,n=l.height,s=l.left,o=l.top,i=Ys(g,w,F.backgroundColor),l={canvas:F.canvas,backgroundColor:i,scale:null!==(l=null!==(l=F.scale)&&void 0!==l?l:t.devicePixelRatio)&&void 0!==l?l:1,x:(null!==(l=F.x)&&void 0!==l?l:0)+s,y:(null!==(l=F.y)&&void 0!==l?l:0)+o,width:null!==(l=F.width)&&void 0!==l?l:Math.ceil(B),height:null!==(l=F.height)&&void 0!==l?l:Math.ceil(n)},c)?(g.logger.debug("Document cloned, using foreign object rendering"),[4,new Os(g,l).render(w)]):[3,3];case 2:return Q=A.sent(),[3,5];case 3:return g.logger.debug("Document cloned, element located at "+s+","+o+" with size "+B+"x"+n+" using computed rendering"),g.logger.debug("Starting DOM parsing"),C=kB(g,w),i===C.styles.backgroundColor&&(C.styles.backgroundColor=Le.TRANSPARENT),g.logger.debug("Starting renderer for element at "+l.x+","+l.y+" with size "+l.width+"x"+l.height),[4,new bs(g,l).render(C)];case 4:Q=A.sent(),A.label=5;case 5:return null!==(C=F.removeContainer)&&void 0!==C&&!C||dn.destroy(r)||g.logger.error("Cannot detach cloned iframe as it is not in the DOM anymore"),g.logger.debug("Finished rendering"),[2,Q]}})})},Ys=function(A,e,t){var r=e.ownerDocument,B=r.documentElement?fe(A,getComputedStyle(r.documentElement).backgroundColor):Le.TRANSPARENT,n=r.body?fe(A,getComputedStyle(r.body).backgroundColor):Le.TRANSPARENT,t="string"==typeof t?fe(A,t):null===t?Le.TRANSPARENT:4294967295;return e===r.documentElement?oe(B)?oe(n)?t:n:B:t};return function(A,e){return Js(A,e=void 0===e?{}:e)}});
33138 33139 33140; 33141////pf: node_modules/sortablejs/Sortable.min.js
vendor: 45,478 bytes, lines 33142-33143
33142/*! Sortable 1.15.7 - MIT | git://github.com/SortableJS/Sortable.git */ 33143!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sortable=e()}(this,function(){"use strict";function o(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,o=Array(e);n<e;n++)o[n]=t[n];return o}function i(t,e,n){return(e=function(t){t=function(t,e){if("object"!=typeof t||!t)return t;var n=t[Symbol.toPrimitive];if(void 0===n)return("string"===e?String:Number)(t);e=n.call(t,e||"default");if("object"!=typeof e)return e;throw new TypeError("@@toPrimitive must return a primitive value.")}(t,"string");return"symbol"==typeof t?t:t+""}(e))in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function a(){return(a=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var n,o=arguments[e];for(n in o)!{}.hasOwnProperty.call(o,n)||(t[n]=o[n])}return t}).apply(null,arguments)}function r(e,t){var n,o=Object.keys(e);return Object.getOwnPropertySymbols&&(n=Object.getOwnPropertySymbols(e),t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),o.push.apply(o,n)),o}function I(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?r(Object(n),!0).forEach(function(t){i(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):r(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function l(t,e){if(null==t)return{};var n,o=function(t,e){if(null==t)return{};var n,o={};for(n in t)if({}.hasOwnProperty.call(t,n)){if(-1!==e.indexOf(n))continue;o[n]=t[n]}return o}(t,e);if(Object.getOwnPropertySymbols)for(var i=Object.getOwnPropertySymbols(t),r=0;r<i.length;r++)n=i[r],-1===e.indexOf(n)&&{}.propertyIsEnumerable.call(t,n)&&(o[n]=t[n]);return o}function e(t){return function(t){if(Array.isArray(t))return o(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(t){if("string"==typeof t)return o(t,e);var n={}.toString.call(t).slice(8,-1);return"Map"===(n="Object"===n&&t.constructor?t.constructor.name:n)||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?o(t,e):void 0}}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function s(t){return(s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function t(t){if("undefined"!=typeof window&&window.navigator)return!!navigator.userAgent.match(t)}var y=t(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i),w=t(/Edge/i),c=t(/firefox/i),u=t(/safari/i)&&!t(/chrome/i)&&!t(/android/i),d=t(/iP(ad|od|hone)/i),n=t(/chrome/i)&&t(/android/i),h={capture:!1,passive:!1};function f(t,e,n){t.addEventListener(e,n,!y&&h)}function p(t,e,n){t.removeEventListener(e,n,!y&&h)}function g(t,e){if(e&&(">"===e[0]&&(e=e.substring(1)),t))try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return}}function m(t){return t.host&&t!==document&&t.host.nodeType&&t.host!==t?t.host:t.parentNode}function P(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"!==e[0]||t.parentNode===n)&&g(t,e)||o&&t===n)return t}while(t!==n&&(t=m(t)))}return null}var v,b=/\s+/g;function k(t,e,n){var o;t&&e&&(t.classList?t.classList[n?"add":"remove"](e):(o=(" "+t.className+" ").replace(b," ").replace(" "+e+" "," "),t.className=(o+(n?" "+e:"")).replace(b," ")))}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];o[e=!(e in o||-1!==e.indexOf("webkit"))?"-webkit-"+e:e]=n+("string"==typeof n?"":"px")}}function D(t,e){var n="";if("string"==typeof t)n=t;else do{var o=R(t,"transform")}while(o&&"none"!==o&&(n=o+" "+n),!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return i&&new i(n)}function E(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i<r;i++)n(o[i],i);return o}return[]}function O(){var t=document.scrollingElement;return t||document.documentElement}function X(t,e,n,o,i){if(t.getBoundingClientRect||t===window){var r,a,l,s,c,u,d=t!==window&&t.parentNode&&t!==O()?(a=(r=t.getBoundingClientRect()).top,l=r.left,s=r.bottom,c=r.right,u=r.height,r.width):(l=a=0,s=window.innerHeight,c=window.innerWidth,u=window.innerHeight,window.innerWidth);if((e||n)&&t!==window&&(i=i||t.parentNode,!y))do{if(i&&i.getBoundingClientRect&&("none"!==R(i,"transform")||n&&"static"!==R(i,"position"))){var h=i.getBoundingClientRect();a-=h.top+parseInt(R(i,"border-top-width")),l-=h.left+parseInt(R(i,"border-left-width")),s=a+r.height,c=l+r.width;break}}while(i=i.parentNode);return o&&t!==window&&(o=(e=D(i||t))&&e.a,t=e&&e.d,e&&(s=(a/=t)+(u/=t),c=(l/=o)+(d/=o))),{top:a,left:l,bottom:s,right:c,width:d,height:u}}}function Y(t,e,n){for(var o=M(t,!0),i=X(t)[e];o;){var r=X(o)[n];if(!("top"===n||"left"===n?r<=i:i<=r))return o;if(o===O())break;o=M(o,!1)}return!1}function B(t,e,n,o){for(var i=0,r=0,a=t.children;r<a.length;){if("none"!==a[r].style.display&&a[r]!==Ht.ghost&&(o||a[r]!==Ht.dragged)&&P(a[r],n.draggable,t,!1)){if(i===e)return a[r];i++}r++}return null}function F(t,e){for(var n=t.lastElementChild;n&&(n===Ht.ghost||"none"===R(n,"display")||e&&!g(n,e));)n=n.previousElementSibling;return n||null}function j(t,e){var n=0;if(!t||!t.parentNode)return-1;for(;t=t.previousElementSibling;)"TEMPLATE"===t.nodeName.toUpperCase()||t===Ht.clone||e&&!g(t,e)||n++;return n}function S(t){var e=0,n=0,o=O();if(t)do{var i=D(t),r=i.a,i=i.d}while(e+=t.scrollLeft*r,n+=t.scrollTop*i,t!==o&&(t=t.parentNode));return[e,n]}function M(t,e){if(!t||!t.getBoundingClientRect)return O();var n=t,o=!1;do{if(n.clientWidth<n.scrollWidth||n.clientHeight<n.scrollHeight){var i=R(n);if(n.clientWidth<n.scrollWidth&&("auto"==i.overflowX||"scroll"==i.overflowX)||n.clientHeight<n.scrollHeight&&("auto"==i.overflowY||"scroll"==i.overflowY)){if(!n.getBoundingClientRect||n===document.body)return O();if(o||e)return n;o=!0}}}while(n=n.parentNode);return O()}function _(t,e){return Math.round(t.top)===Math.round(e.top)&&Math.round(t.left)===Math.round(e.left)&&Math.round(t.height)===Math.round(e.height)&&Math.round(t.width)===Math.round(e.width)}function C(e,n){return function(){var t;v||(1===(t=arguments).length?e.call(this,t[0]):e.apply(this,t),v=setTimeout(function(){v=void 0},n))}}function H(t,e,n){t.scrollLeft+=e,t.scrollTop+=n}function T(t){var e=window.Polymer,n=window.jQuery||window.Zepto;return e&&e.dom?e.dom(t).cloneNode(!0):n?n(t).clone(!0)[0]:t.cloneNode(!0)}function x(t,e){R(t,"position","absolute"),R(t,"top",e.top),R(t,"left",e.left),R(t,"width",e.width),R(t,"height",e.height)}function A(t){R(t,"position",""),R(t,"top",""),R(t,"left",""),R(t,"width",""),R(t,"height","")}function L(n,o,i){var r={};return Array.from(n.children).forEach(function(t){var e;P(t,o.draggable,n,!1)&&!t.animated&&t!==i&&(e=X(t),r.left=Math.min(null!==(t=r.left)&&void 0!==t?t:1/0,e.left),r.top=Math.min(null!==(t=r.top)&&void 0!==t?t:1/0,e.top),r.right=Math.max(null!==(t=r.right)&&void 0!==t?t:-1/0,e.right),r.bottom=Math.max(null!==(t=r.bottom)&&void 0!==t?t:-1/0,e.bottom))}),r.width=r.right-r.left,r.height=r.bottom-r.top,r.x=r.left,r.y=r.top,r}var K="Sortable"+(new Date).getTime();function N(){var e,o=[];return{captureAnimationState:function(){o=[],this.options.animation&&[].slice.call(this.el.children).forEach(function(t){var e,n;"none"!==R(t,"display")&&t!==Ht.ghost&&(o.push({target:t,rect:X(t)}),e=I({},o[o.length-1].rect),!t.thisAnimationDuration||(n=D(t,!0))&&(e.top-=n.f,e.left-=n.e),t.fromRect=e)})},addAnimationState:function(t){o.push(t)},removeAnimationState:function(t){o.splice(function(t,e){for(var n in t)if(t.hasOwnProperty(n))for(var o in e)if(e.hasOwnProperty(o)&&e[o]===t[n][o])return Number(n);return-1}(o,{target:t}),1)},animateAll:function(t){var c=this;if(!this.options.animation)return clearTimeout(e),void("function"==typeof t&&t());var u=!1,d=0;o.forEach(function(t){var e=0,n=t.target,o=n.fromRect,i=X(n),r=n.prevFromRect,a=n.prevToRect,l=t.rect,s=D(n,!0);s&&(i.top-=s.f,i.left-=s.e),n.toRect=i,n.thisAnimationDuration&&_(r,i)&&!_(o,i)&&(l.top-i.top)/(l.left-i.left)==(o.top-i.top)/(o.left-i.left)&&(t=l,s=r,r=a,a=c.options,e=Math.sqrt(Math.pow(s.top-t.top,2)+Math.pow(s.left-t.left,2))/Math.sqrt(Math.pow(s.top-r.top,2)+Math.pow(s.left-r.left,2))*a.animation),_(i,o)||(n.prevFromRect=o,n.prevToRect=i,e=e||c.options.animation,c.animate(n,l,i,e)),e&&(u=!0,d=Math.max(d,e),clearTimeout(n.animationResetTimer),n.animationResetTimer=setTimeout(function(){n.animationTime=0,n.prevFromRect=null,n.fromRect=null,n.prevToRect=null,n.thisAnimationDuration=null},e),n.thisAnimationDuration=e)}),clearTimeout(e),u?e=setTimeout(function(){"function"==typeof t&&t()},d):"function"==typeof t&&t(),o=[]},animate:function(t,e,n,o){var i,r;o&&(R(t,"transition",""),R(t,"transform",""),i=(r=D(this.el))&&r.a,r=r&&r.d,i=(e.left-n.left)/(i||1),r=(e.top-n.top)/(r||1),t.animatingX=!!i,t.animatingY=!!r,R(t,"transform","translate3d("+i+"px,"+r+"px,0)"),this.forRepaintDummy=t.offsetWidth,R(t,"transition","transform "+o+"ms"+(this.options.easing?" "+this.options.easing:"")),R(t,"transform","translate3d(0,0,0)"),"number"==typeof t.animated&&clearTimeout(t.animated),t.animated=setTimeout(function(){R(t,"transition",""),R(t,"transform",""),t.animated=!1,t.animatingX=!1,t.animatingY=!1},o))}}}var W=[],z={initializeByDefault:!0},G={mount:function(e){for(var t in z)!z.hasOwnProperty(t)||t in e||(e[t]=z[t]);W.forEach(function(t){if(t.pluginName===e.pluginName)throw"Sortable: Cannot mount plugin ".concat(e.pluginName," more than once")}),W.push(e)},pluginEvent:function(e,n,o){var t=this;this.eventCanceled=!1,o.cancel=function(){t.eventCanceled=!0};var i=e+"Global";W.forEach(function(t){n[t.pluginName]&&(n[t.pluginName][i]&&n[t.pluginName][i](I({sortable:n},o)),n.options[t.pluginName]&&n[t.pluginName][e]&&n[t.pluginName][e](I({sortable:n},o)))})},initializePlugins:function(n,o,i,t){for(var e in W.forEach(function(t){var e=t.pluginName;(n.options[e]||t.initializeByDefault)&&((t=new t(n,o,n.options)).sortable=n,t.options=n.options,n[e]=t,a(i,t.defaults))}),n.options){var r;n.options.hasOwnProperty(e)&&(void 0!==(r=this.modifyOption(n,e,n.options[e]))&&(n.options[e]=r))}},getEventProperties:function(e,n){var o={};return W.forEach(function(t){"function"==typeof t.eventProperties&&a(o,t.eventProperties.call(n[t.pluginName],e))}),o},modifyOption:function(e,n,o){var i;return W.forEach(function(t){e[t.pluginName]&&t.optionListeners&&"function"==typeof t.optionListeners[n]&&(i=t.optionListeners[n].call(e[t.pluginName],o))}),i}};function U(t){var e=t.sortable,n=t.rootEl,o=t.name,i=t.targetEl,r=t.cloneEl,a=t.toEl,l=t.fromEl,s=t.oldIndex,c=t.newIndex,u=t.oldDraggableIndex,d=t.newDraggableIndex,h=t.originalEvent,f=t.putSortable,p=t.extraEventProperties;if(e=e||n&&n[K]){var g,m=e.options,t="on"+o.charAt(0).toUpperCase()+o.substr(1);!window.CustomEvent||y||w?(g=document.createEvent("Event")).initEvent(o,!0,!0):g=new CustomEvent(o,{bubbles:!0,cancelable:!0}),g.to=a||n,g.from=l||n,g.item=i||n,g.clone=r,g.oldIndex=s,g.newIndex=c,g.oldDraggableIndex=u,g.newDraggableIndex=d,g.originalEvent=h,g.pullMode=f?f.lastPutMode:void 0;var v,b=I(I({},p),G.getEventProperties(o,e));for(v in b)g[v]=b[v];n&&n.dispatchEvent(g),m[t]&&m[t].call(e,g)}}function q(t,e){var n=(o=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{}).evt,o=l(o,V);G.pluginEvent.bind(Ht)(t,e,I({dragEl:$,parentEl:Q,ghostEl:J,rootEl:tt,nextEl:et,lastDownEl:nt,cloneEl:ot,cloneHidden:it,dragStarted:vt,putSortable:ut,activeSortable:Ht.active,originalEvent:n,oldIndex:rt,oldDraggableIndex:lt,newIndex:at,newDraggableIndex:st,hideGhostForTarget:Yt,unhideGhostForTarget:Bt,cloneNowHidden:function(){it=!0},cloneNowShown:function(){it=!1},dispatchSortableEvent:function(t){Z({sortable:e,name:t,originalEvent:n})}},o))}var V=["evt"];function Z(t){U(I({putSortable:ut,cloneEl:ot,targetEl:$,rootEl:tt,oldIndex:rt,oldDraggableIndex:lt,newIndex:at,newDraggableIndex:st},t))}var $,Q,J,tt,et,nt,ot,it,rt,at,lt,st,ct,ut,dt,ht,ft,pt,gt,mt,vt,bt,yt,wt,Dt,Et=!1,St=!1,_t=[],Ct=!1,Tt=!1,xt=[],Ot=!1,Mt=[],At="undefined"!=typeof document,Nt=d,It=w||y?"cssFloat":"float",Pt=At&&!n&&!d&&"draggable"in document.createElement("div"),kt=function(){if(At){if(y)return!1;var t=document.createElement("x");return t.style.cssText="pointer-events:auto","auto"===t.style.pointerEvents}}(),Rt=function(t,e){var n=R(t),o=parseInt(n.width)-parseInt(n.paddingLeft)-parseInt(n.paddingRight)-parseInt(n.borderLeftWidth)-parseInt(n.borderRightWidth),i=B(t,0,e),r=B(t,1,e),a=i&&R(i),l=r&&R(r),s=a&&parseInt(a.marginLeft)+parseInt(a.marginRight)+X(i).width,t=l&&parseInt(l.marginLeft)+parseInt(l.marginRight)+X(r).width;if("flex"===n.display)return"column"===n.flexDirection||"column-reverse"===n.flexDirection?"vertical":"horizontal";if("grid"===n.display)return n.gridTemplateColumns.split(" ").length<=1?"vertical":"horizontal";if(i&&a.float&&"none"!==a.float){e="left"===a.float?"left":"right";return!r||"both"!==l.clear&&l.clear!==e?"horizontal":"vertical"}return i&&("block"===a.display||"flex"===a.display||"table"===a.display||"grid"===a.display||o<=s&&"none"===n[It]||r&&"none"===n[It]&&o<s+t)?"vertical":"horizontal"},Xt=function(t){function l(r,a){return function(t,e,n,o){var i=t.options.group.name&&e.options.group.name&&t.options.group.name===e.options.group.name;if(null==r&&(a||i))return!0;if(null==r||!1===r)return!1;if(a&&"clone"===r)return r;if("function"==typeof r)return l(r(t,e,n,o),a)(t,e,n,o);e=(a?t:e).options.group.name;return!0===r||"string"==typeof r&&r===e||r.join&&-1<r.indexOf(e)}}var e={},n=t.group;n&&"object"==s(n)||(n={name:n}),e.name=n.name,e.checkPull=l(n.pull,!0),e.checkPut=l(n.put),e.revertClone=n.revertClone,t.group=e},Yt=function(){!kt&&J&&R(J,"display","none")},Bt=function(){!kt&&J&&R(J,"display","")};At&&!n&&document.addEventListener("click",function(t){if(St)return t.preventDefault(),t.stopPropagation&&t.stopPropagation(),t.stopImmediatePropagation&&t.stopImmediatePropagation(),St=!1},!0);function Ft(t){if($){t=t.touches?t.touches[0]:t;var e=(i=t.clientX,r=t.clientY,_t.some(function(t){var e=t[K].options.emptyInsertThreshold;if(e&&!F(t)){var n=X(t),o=i>=n.left-e&&i<=n.right+e,e=r>=n.top-e&&r<=n.bottom+e;return o&&e?a=t:void 0}}),a);if(e){var n,o={};for(n in t)t.hasOwnProperty(n)&&(o[n]=t[n]);o.target=o.rootEl=e,o.preventDefault=void 0,o.stopPropagation=void 0,e[K]._onDragOver(o)}}var i,r,a}function jt(t){$&&$.parentNode[K]._isOutsideThisEl(t.target)}function Ht(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[K]=this;var n,o,i={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return Rt(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Ht.supportPointer&&"PointerEvent"in window&&(!u||d),emptyInsertThreshold:5};for(n in G.initializePlugins(this,t,i),i)n in e||(e[n]=i[n]);for(o in Xt(e),this)"_"===o.charAt(0)&&"function"==typeof this[o]&&(this[o]=this[o].bind(this));this.nativeDraggable=!e.forceFallback&&Pt,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?f(t,"pointerdown",this._onTapStart):(f(t,"mousedown",this._onTapStart),f(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(f(t,"dragover",this),f(t,"dragenter",this)),_t.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,N())}function Lt(t,e,n,o,i,r,a,l){var s,c,u=t[K],d=u.options.onMove;return!window.CustomEvent||y||w?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||X(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),c=d?d.call(u,s,a):c}function Kt(t){t.draggable=!1}function Wt(){Ot=!1}function zt(t){return setTimeout(t,0)}function Gt(t){return clearTimeout(t)}Ht.prototype={constructor:Ht,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(bt=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,$):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(!function(t){Mt.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&Mt.push(o)}}(o),!$&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled)&&!s.isContentEditable&&(this.nativeDraggable||!u||!l||"SELECT"!==l.tagName.toUpperCase())&&!((l=P(l,t.draggable,o,!1))&&l.animated||nt===l)){if(rt=j(l),lt=j(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return Z({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),q("filter",n,{evt:e}),void(i&&e.preventDefault())}else if(c=c&&c.split(",").some(function(t){if(t=P(s,t.trim(),o,!1))return Z({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),q("filter",n,{evt:e}),!0}))return void(i&&e.preventDefault());t.handle&&!P(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;n&&!$&&n.parentNode===r&&(o=X(n),tt=r,Q=($=n).parentNode,et=$.nextSibling,nt=n,ct=a.group,dt={target:Ht.dragged=$,clientX:(e||t).clientX,clientY:(e||t).clientY},gt=dt.clientX-o.left,mt=dt.clientY-o.top,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,$.style["will-change"]="all",o=function(){q("delayEnded",i,{evt:t}),Ht.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!c&&i.nativeDraggable&&($.draggable=!0),i._triggerDragStart(t,e),Z({sortable:i,name:"choose",originalEvent:t}),k($,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){E($,t.trim(),Kt)}),f(l,"dragover",Ft),f(l,"mousemove",Ft),f(l,"touchmove",Ft),a.supportPointer?(f(l,"pointerup",i._onDrop),this.nativeDraggable||f(l,"pointercancel",i._onDrop)):(f(l,"mouseup",i._onDrop),f(l,"touchend",i._onDrop),f(l,"touchcancel",i._onDrop)),c&&this.nativeDraggable&&(this.options.touchStartThreshold=4,$.draggable=!0),q("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(w||y)?o():Ht.eventCanceled?this._onDrop():(a.supportPointer?(f(l,"pointerup",i._disableDelayedDrag),f(l,"pointercancel",i._disableDelayedDrag)):(f(l,"mouseup",i._disableDelayedDrag),f(l,"touchend",i._disableDelayedDrag),f(l,"touchcancel",i._disableDelayedDrag)),f(l,"mousemove",i._delayedDragTouchMoveHandler),f(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&f(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)))},_delayedDragTouchMoveHandler:function(t){t=t.touches?t.touches[0]:t;Math.max(Math.abs(t.clientX-this._lastX),Math.abs(t.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){$&&Kt($),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;p(t,"mouseup",this._disableDelayedDrag),p(t,"touchend",this._disableDelayedDrag),p(t,"touchcancel",this._disableDelayedDrag),p(t,"pointerup",this._disableDelayedDrag),p(t,"pointercancel",this._disableDelayedDrag),p(t,"mousemove",this._delayedDragTouchMoveHandler),p(t,"touchmove",this._delayedDragTouchMoveHandler),p(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?f(document,"pointermove",this._onTouchMove):f(document,e?"touchmove":"mousemove",this._onTouchMove):(f($,"dragend",this),f(tt,"dragstart",this._onDragStart));try{document.selection?zt(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){var n;Et=!1,tt&&$?(q("dragStarted",this,{evt:e}),this.nativeDraggable&&f(document,"dragover",jt),n=this.options,t||k($,n.dragClass,!1),k($,n.ghostClass,!0),Ht.active=this,t&&this._appendGhost(),Z({sortable:this,name:"start",originalEvent:e})):this._nulling()},_emulateDragOver:function(){if(ht){this._lastX=ht.clientX,this._lastY=ht.clientY,Yt();for(var t=document.elementFromPoint(ht.clientX,ht.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(ht.clientX,ht.clientY))!==e;)e=t;if($.parentNode[K]._isOutsideThisEl(t),e)do{if(e[K])if(e[K]._onDragOver({clientX:ht.clientX,clientY:ht.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}while(e=m(t=e));Bt()}},_onTouchMove:function(t){if(dt){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=J&&D(J,!0),a=J&&r&&r.a,l=J&&r&&r.d,e=Nt&&Dt&&S(Dt),a=(i.clientX-dt.clientX+o.x)/(a||1)+(e?e[0]-xt[0]:0)/(a||1),l=(i.clientY-dt.clientY+o.y)/(l||1)+(e?e[1]-xt[1]:0)/(l||1);if(!Ht.active&&!Et){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))<n)return;this._onDragStart(t,!0)}J&&(r?(r.e+=a-(ft||0),r.f+=l-(pt||0)):r={a:1,b:0,c:0,d:1,e:a,f:l},r="matrix(".concat(r.a,",").concat(r.b,",").concat(r.c,",").concat(r.d,",").concat(r.e,",").concat(r.f,")"),R(J,"webkitTransform",r),R(J,"mozTransform",r),R(J,"msTransform",r),R(J,"transform",r),ft=a,pt=l,ht=i),t.cancelable&&t.preventDefault()}},_appendGhost:function(){if(!J){var t=this.options.fallbackOnBody?document.body:tt,e=X($,!0,Nt,!0,t),n=this.options;if(Nt){for(Dt=t;"static"===R(Dt,"position")&&"none"===R(Dt,"transform")&&Dt!==document;)Dt=Dt.parentNode;Dt!==document.body&&Dt!==document.documentElement?(Dt===document&&(Dt=O()),e.top+=Dt.scrollTop,e.left+=Dt.scrollLeft):Dt=O(),xt=S(Dt)}k(J=$.cloneNode(!0),n.ghostClass,!1),k(J,n.fallbackClass,!0),k(J,n.dragClass,!0),R(J,"transition",""),R(J,"transform",""),R(J,"box-sizing","border-box"),R(J,"margin",0),R(J,"top",e.top),R(J,"left",e.left),R(J,"width",e.width),R(J,"height",e.height),R(J,"opacity","0.8"),R(J,"position",Nt?"absolute":"fixed"),R(J,"zIndex","100000"),R(J,"pointerEvents","none"),Ht.ghost=J,t.appendChild(J),R(J,"transform-origin",gt/parseInt(J.style.width)*100+"% "+mt/parseInt(J.style.height)*100+"%")}},_onDragStart:function(t,e){var n=this,o=t.dataTransfer,i=n.options;q("dragStart",this,{evt:t}),Ht.eventCanceled?this._onDrop():(q("setupClone",this),Ht.eventCanceled||((ot=T($)).removeAttribute("id"),ot.draggable=!1,ot.style["will-change"]="",this._hideClone(),k(ot,this.options.chosenClass,!1),Ht.clone=ot),n.cloneId=zt(function(){q("clone",n),Ht.eventCanceled||(n.options.removeCloneOnHide||tt.insertBefore(ot,$),n._hideClone(),Z({sortable:n,name:"clone"}))}),e||k($,i.dragClass,!0),e?(St=!0,n._loopId=setInterval(n._emulateDragOver,50)):(p(document,"mouseup",n._onDrop),p(document,"touchend",n._onDrop),p(document,"touchcancel",n._onDrop),o&&(o.effectAllowed="move",i.setData&&i.setData.call(n,o,$)),f(document,"drop",n),R($,"transform","translateZ(0)")),Et=!0,n._dragStartId=zt(n._dragStarted.bind(n,e,t)),f(document,"selectstart",n),vt=!0,window.getSelection().removeAllRanges(),u&&R(document.body,"user-select","none"))},_onDragOver:function(n){var o,i,r,t,e,a=this.el,l=n.target,s=this.options,c=s.group,u=Ht.active,d=ct===c,h=s.sort,f=ut||u,p=this,g=!1;if(!Ot){if(void 0!==n.preventDefault&&n.cancelable&&n.preventDefault(),l=P(l,s.draggable,a,!0),O("dragOver"),Ht.eventCanceled)return g;if($.contains(n.target)||l.animated&&l.animatingX&&l.animatingY||p._ignoreWhileAnimating===l)return A(!1);if(St=!1,u&&!s.disabled&&(d?h||(i=Q!==tt):ut===this||(this.lastPutMode=ct.checkPull(this,u,$,n))&&c.checkPut(this,u,$,n))){if(r="vertical"===this._getDirection(n,l),o=X($),O("dragOverValid"),Ht.eventCanceled)return g;if(i)return Q=tt,M(),this._hideClone(),O("revert"),Ht.eventCanceled||(et?tt.insertBefore($,et):tt.appendChild($)),A(!0);var m=F(a,s.draggable);if(m&&(S=n,c=r,x=X(F((E=this).el,E.options.draggable)),E=L(E.el,E.options,J),!(c?S.clientX>E.right+10||S.clientY>x.bottom&&S.clientX>x.left:S.clientY>E.bottom+10||S.clientX>x.right&&S.clientY>x.top)||m.animated)){if(m&&(t=n,e=r,C=X(B((_=this).el,0,_.options,!0)),_=L(_.el,_.options,J),e?t.clientX<_.left-10||t.clientY<C.top&&t.clientX<C.right:t.clientY<_.top-10||t.clientY<C.bottom&&t.clientX<C.left)){var v=B(a,0,s,!0);if(v===$)return A(!1);if(D=X(l=v),!1!==Lt(tt,a,$,o,l,D,n,!1))return M(),a.insertBefore($,v),Q=a,N(),A(!0)}else if(l.parentNode===a){var b,y,w,D=X(l),E=$.parentNode!==a,S=(S=$.animated&&$.toRect||o,x=l.animated&&l.toRect||D,_=(e=r)?S.left:S.top,t=e?S.right:S.bottom,C=e?S.width:S.height,v=e?x.left:x.top,S=e?x.right:x.bottom,x=e?x.width:x.height,!(_===v||t===S||_+C/2===v+x/2)),_=r?"top":"left",C=Y(l,"top","top")||Y($,"top","top"),v=C?C.scrollTop:void 0;if(bt!==l&&(y=D[_],Ct=!1,Tt=!S&&s.invertSwap||E),0!==(b=function(t,e,n,o,i,r,a,l){var s=o?t.clientY:t.clientX,c=o?n.height:n.width,t=o?n.top:n.left,o=o?n.bottom:n.right,n=!1;if(!a)if(l&&wt<c*i){if(Ct=!Ct&&(1===yt?t+c*r/2<s:s<o-c*r/2)?!0:Ct)n=!0;else if(1===yt?s<t+wt:o-wt<s)return-yt}else if(t+c*(1-i)/2<s&&s<o-c*(1-i)/2)return function(t){return j($)<j(t)?1:-1}(e);if((n=n||a)&&(s<t+c*r/2||o-c*r/2<s))return t+c/2<s?1:-1;return 0}(n,l,D,r,S?1:s.swapThreshold,null==s.invertedSwapThreshold?s.swapThreshold:s.invertedSwapThreshold,Tt,bt===l)))for(var T=j($);(w=Q.children[T-=b])&&("none"===R(w,"display")||w===J););if(0===b||w===l)return A(!1);yt=b;var x=(bt=l).nextElementSibling,E=!1,S=Lt(tt,a,$,o,l,D,n,E=1===b);if(!1!==S)return 1!==S&&-1!==S||(E=1===S),Ot=!0,setTimeout(Wt,30),M(),E&&!x?a.appendChild($):l.parentNode.insertBefore($,E?x:l),C&&H(C,0,v-C.scrollTop),Q=$.parentNode,void 0===y||Tt||(wt=Math.abs(y-X(l)[_])),N(),A(!0)}}else{if(m===$)return A(!1);if((l=m&&a===n.target?m:l)&&(D=X(l)),!1!==Lt(tt,a,$,o,l,D,n,!!l))return M(),m&&m.nextSibling?a.insertBefore($,m.nextSibling):a.appendChild($),Q=a,N(),A(!0)}if(a.contains($))return A(!1)}return!1}function O(t,e){q(t,p,I({evt:n,isOwner:d,axis:r?"vertical":"horizontal",revert:i,dragRect:o,targetRect:D,canSort:h,fromSortable:f,target:l,completed:A,onMove:function(t,e){return Lt(tt,a,$,o,t,X(t),n,e)},changed:N},e))}function M(){O("dragOverAnimationCapture"),p.captureAnimationState(),p!==f&&f.captureAnimationState()}function A(t){return O("dragOverCompleted",{insertion:t}),t&&(d?u._hideClone():u._showClone(p),p!==f&&(k($,(ut||u).options.ghostClass,!1),k($,s.ghostClass,!0)),ut!==p&&p!==Ht.active?ut=p:p===Ht.active&&ut&&(ut=null),f===p&&(p._ignoreWhileAnimating=l),p.animateAll(function(){O("dragOverAnimationComplete"),p._ignoreWhileAnimating=null}),p!==f&&(f.animateAll(),f._ignoreWhileAnimating=null)),(l===$&&!$.animated||l===a&&!l.animated)&&(bt=null),s.dragoverBubble||n.rootEl||l===document||($.parentNode[K]._isOutsideThisEl(n.target),t||Ft(n)),!s.dragoverBubble&&n.stopPropagation&&n.stopPropagation(),g=!0}function N(){at=j($),st=j($,s.draggable),Z({sortable:p,name:"change",toEl:a,newIndex:at,newDraggableIndex:st,originalEvent:n})}},_ignoreWhileAnimating:null,_offMoveEvents:function(){p(document,"mousemove",this._onTouchMove),p(document,"touchmove",this._onTouchMove),p(document,"pointermove",this._onTouchMove),p(document,"dragover",Ft),p(document,"mousemove",Ft),p(document,"touchmove",Ft)},_offUpEvents:function(){var t=this.el.ownerDocument;p(t,"mouseup",this._onDrop),p(t,"touchend",this._onDrop),p(t,"pointerup",this._onDrop),p(t,"pointercancel",this._onDrop),p(t,"touchcancel",this._onDrop),p(document,"selectstart",this)},_onDrop:function(t){var e=this.el,n=this.options;at=j($),st=j($,n.draggable),q("drop",this,{evt:t}),Q=$&&$.parentNode,at=j($),st=j($,n.draggable),Ht.eventCanceled||(Ct=Tt=Et=!1,clearInterval(this._loopId),clearTimeout(this._dragStartTimer),Gt(this.cloneId),Gt(this._dragStartId),this.nativeDraggable&&(p(document,"drop",this),p(e,"dragstart",this._onDragStart)),this._offMoveEvents(),this._offUpEvents(),u&&R(document.body,"user-select",""),R($,"transform",""),t&&(vt&&(t.cancelable&&t.preventDefault(),n.dropBubble||t.stopPropagation()),J&&J.parentNode&&J.parentNode.removeChild(J),(tt===Q||ut&&"clone"!==ut.lastPutMode)&&ot&&ot.parentNode&&ot.parentNode.removeChild(ot),$&&(this.nativeDraggable&&p($,"dragend",this),Kt($),$.style["will-change"]="",vt&&!Et&&k($,(ut||this).options.ghostClass,!1),k($,this.options.chosenClass,!1),Z({sortable:this,name:"unchoose",toEl:Q,newIndex:null,newDraggableIndex:null,originalEvent:t}),tt!==Q?(0<=at&&(Z({rootEl:Q,name:"add",toEl:Q,fromEl:tt,originalEvent:t}),Z({sortable:this,name:"remove",toEl:Q,originalEvent:t}),Z({rootEl:Q,name:"sort",toEl:Q,fromEl:tt,originalEvent:t}),Z({sortable:this,name:"sort",toEl:Q,originalEvent:t})),ut&&ut.save()):at!==rt&&0<=at&&(Z({sortable:this,name:"update",toEl:Q,originalEvent:t}),Z({sortable:this,name:"sort",toEl:Q,originalEvent:t})),Ht.active&&(null!=at&&-1!==at||(at=rt,st=lt),Z({sortable:this,name:"end",toEl:Q,originalEvent:t}),this.save())))),this._nulling()},_nulling:function(){q("nulling",this),tt=$=Q=J=et=ot=nt=it=dt=ht=vt=at=st=rt=lt=bt=yt=ut=ct=Ht.dragged=Ht.ghost=Ht.clone=Ht.active=null;var e=this.el;Mt.forEach(function(t){e.contains(t)&&(t.checked=!0)}),Mt.length=ft=pt=0},handleEvent:function(t){switch(t.type){case"drop":case"dragend":this._onDrop(t);break;case"dragenter":case"dragover":$&&(this._onDragOver(t),function(t){t.dataTransfer&&(t.dataTransfer.dropEffect="move");t.cancelable&&t.preventDefault()}(t));break;case"selectstart":t.preventDefault()}},toArray:function(){for(var t,e=[],n=this.el.children,o=0,i=n.length,r=this.options;o<i;o++)P(t=n[o],r.draggable,this.el,!1)&&e.push(t.getAttribute(r.dataIdAttr)||function(t){var e=t.tagName+t.className+t.src+t.href+t.textContent,n=e.length,o=0;for(;n--;)o+=e.charCodeAt(n);return o.toString(36)}(t));return e},sort:function(t,e){var n={},o=this.el;this.toArray().forEach(function(t,e){e=o.children[e];P(e,this.options.draggable,o,!1)&&(n[t]=e)},this),e&&this.captureAnimationState(),t.forEach(function(t){n[t]&&(o.removeChild(n[t]),o.appendChild(n[t]))}),e&&this.animateAll()},save:function(){var t=this.options.store;t&&t.set&&t.set(this)},closest:function(t,e){return P(t,e||this.options.draggable,this.el,!1)},option:function(t,e){var n=this.options;if(void 0===e)return n[t];var o=G.modifyOption(this,t,e);n[t]=void 0!==o?o:e,"group"===t&&Xt(n)},destroy:function(){q("destroy",this);var t=this.el;t[K]=null,p(t,"mousedown",this._onTapStart),p(t,"touchstart",this._onTapStart),p(t,"pointerdown",this._onTapStart),this.nativeDraggable&&(p(t,"dragover",this),p(t,"dragenter",this)),Array.prototype.forEach.call(t.querySelectorAll("[draggable]"),function(t){t.removeAttribute("draggable")}),this._onDrop(),this._disableDelayedDragEvents(),_t.splice(_t.indexOf(this.el),1),this.el=t=null},_hideClone:function(){it||(q("hideClone",this),Ht.eventCanceled||(R(ot,"display","none"),this.options.removeCloneOnHide&&ot.parentNode&&ot.parentNode.removeChild(ot),it=!0))},_showClone:function(t){"clone"===t.lastPutMode?it&&(q("showClone",this),Ht.eventCanceled||($.parentNode!=tt||this.options.group.revertClone?et?tt.insertBefore(ot,et):tt.appendChild(ot):tt.insertBefore(ot,$),this.options.group.revertClone&&this.animate($,ot),R(ot,"display",""),it=!1)):this._hideClone()}},At&&f(document,"touchmove",function(t){(Ht.active||Et)&&t.cancelable&&t.preventDefault()}),Ht.utils={on:f,off:p,css:R,find:E,is:function(t,e){return!!P(t,e,t,!1)},extend:function(t,e){if(t&&e)for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t},throttle:C,closest:P,toggleClass:k,clone:T,index:j,nextTick:zt,cancelNextTick:Gt,detectDirection:Rt,getChild:B,expando:K},Ht.get=function(t){return t[K]},Ht.mount=function(){for(var t=arguments.length,e=new Array(t),n=0;n<t;n++)e[n]=arguments[n];(e=e[0].constructor===Array?e[0]:e).forEach(function(t){if(!t.prototype||!t.prototype.constructor)throw"Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(t));t.utils&&(Ht.utils=I(I({},Ht.utils),t.utils)),G.mount(t)})},Ht.create=function(t,e){return new Ht(t,e)};var Ut,qt,Vt,Zt,$t,Qt,Jt=[],te=!(Ht.version="1.15.7");function ee(){Jt.forEach(function(t){clearInterval(t.pid)}),Jt=[]}function ne(){clearInterval(Qt)}var oe,ie=C(function(n,t,e,o){if(t.scroll){var i,r=(n.touches?n.touches[0]:n).clientX,a=(n.touches?n.touches[0]:n).clientY,l=t.scrollSensitivity,s=t.scrollSpeed,c=O(),u=!1;qt!==e&&(qt=e,ee(),Ut=t.scroll,i=t.scrollFn,!0===Ut&&(Ut=M(e,!0)));var d=0,h=Ut;do{var f=h,p=X(f),g=p.top,m=p.bottom,v=p.left,b=p.right,y=p.width,w=p.height,D=void 0,E=void 0,S=f.scrollWidth,_=f.scrollHeight,C=R(f),T=f.scrollLeft,p=f.scrollTop,E=f===c?(D=y<S&&("auto"===C.overflowX||"scroll"===C.overflowX||"visible"===C.overflowX),w<_&&("auto"===C.overflowY||"scroll"===C.overflowY||"visible"===C.overflowY)):(D=y<S&&("auto"===C.overflowX||"scroll"===C.overflowX),w<_&&("auto"===C.overflowY||"scroll"===C.overflowY)),T=D&&(Math.abs(b-r)<=l&&T+y<S)-(Math.abs(v-r)<=l&&!!T),p=E&&(Math.abs(m-a)<=l&&p+w<_)-(Math.abs(g-a)<=l&&!!p);if(!Jt[d])for(var x=0;x<=d;x++)Jt[x]||(Jt[x]={});Jt[d].vx==T&&Jt[d].vy==p&&Jt[d].el===f||(Jt[d].el=f,Jt[d].vx=T,Jt[d].vy=p,clearInterval(Jt[d].pid),0==T&&0==p||(u=!0,Jt[d].pid=setInterval(function(){o&&0===this.layer&&Ht.active._onTouchMove($t);var t=Jt[this.layer].vy?Jt[this.layer].vy*s:0,e=Jt[this.layer].vx?Jt[this.layer].vx*s:0;"function"==typeof i&&"continue"!==i.call(Ht.dragged.parentNode[K],e,t,n,$t,Jt[this.layer].el)||H(Jt[this.layer].el,e,t)}.bind({layer:d}),24))),d++}while(t.bubbleScroll&&h!==c&&(h=M(h,!1)));te=u}},30),n=function(t){var e=t.originalEvent,n=t.putSortable,o=t.dragEl,i=t.activeSortable,r=t.dispatchSortableEvent,a=t.hideGhostForTarget,t=t.unhideGhostForTarget;e&&(i=n||i,a(),e=e.changedTouches&&e.changedTouches.length?e.changedTouches[0]:e,e=document.elementFromPoint(e.clientX,e.clientY),t(),i&&!i.el.contains(e)&&(r("spill"),this.onSpill({dragEl:o,putSortable:n})))};function re(){}function ae(){}re.prototype={startIndex:null,dragStart:function(t){t=t.oldDraggableIndex;this.startIndex=t},onSpill:function(t){var e=t.dragEl,n=t.putSortable;this.sortable.captureAnimationState(),n&&n.captureAnimationState();t=B(this.sortable.el,this.startIndex,this.options);t?this.sortable.el.insertBefore(e,t):this.sortable.el.appendChild(e),this.sortable.animateAll(),n&&n.animateAll()},drop:n},a(re,{pluginName:"revertOnSpill"}),ae.prototype={onSpill:function(t){var e=t.dragEl,t=t.putSortable||this.sortable;t.captureAnimationState(),e.parentNode&&e.parentNode.removeChild(e),t.animateAll()},drop:n},a(ae,{pluginName:"removeOnSpill"});var le,se,ce,ue,de,he=[],fe=[],pe=!1,ge=!1,me=!1;function ve(n,o){fe.forEach(function(t,e){e=o.children[t.sortableIndex+(n?Number(e):0)];e?o.insertBefore(t,e):o.appendChild(t)})}function be(){he.forEach(function(t){t!==ce&&t.parentNode&&t.parentNode.removeChild(t)})}return Ht.mount(new function(){function t(){for(var t in this.defaults={scroll:!0,forceAutoScrollFallback:!1,scrollSensitivity:30,scrollSpeed:10,bubbleScroll:!0},this)"_"===t.charAt(0)&&"function"==typeof this[t]&&(this[t]=this[t].bind(this))}return t.prototype={dragStarted:function(t){t=t.originalEvent;this.sortable.nativeDraggable?f(document,"dragover",this._handleAutoScroll):this.options.supportPointer?f(document,"pointermove",this._handleFallbackAutoScroll):t.touches?f(document,"touchmove",this._handleFallbackAutoScroll):f(document,"mousemove",this._handleFallbackAutoScroll)},dragOverCompleted:function(t){t=t.originalEvent;this.options.dragOverBubble||t.rootEl||this._handleAutoScroll(t)},drop:function(){this.sortable.nativeDraggable?p(document,"dragover",this._handleAutoScroll):(p(document,"pointermove",this._handleFallbackAutoScroll),p(document,"touchmove",this._handleFallbackAutoScroll),p(document,"mousemove",this._handleFallbackAutoScroll)),ne(),ee(),clearTimeout(v),v=void 0},nulling:function(){$t=qt=Ut=te=Qt=Vt=Zt=null,Jt.length=0},_handleFallbackAutoScroll:function(t){this._handleAutoScroll(t,!0)},_handleAutoScroll:function(e,n){var o,i=this,r=(e.touches?e.touches[0]:e).clientX,a=(e.touches?e.touches[0]:e).clientY,t=document.elementFromPoint(r,a);$t=e,n||this.options.forceAutoScrollFallback||w||y||u?(ie(e,this.options,t,n),o=M(t,!0),!te||Qt&&r===Vt&&a===Zt||(Qt&&ne(),Qt=setInterval(function(){var t=M(document.elementFromPoint(r,a),!0);t!==o&&(o=t,ee()),ie(e,i.options,t,n)},10),Vt=r,Zt=a)):this.options.bubbleScroll&&M(t,!0)!==O()?ie(e,this.options,M(t,!1),!1):ee()}},a(t,{pluginName:"scroll",initializeByDefault:!0})}),Ht.mount(ae,re),Ht.mount(new function(){function t(){this.defaults={swapClass:"sortable-swap-highlight"}}return t.prototype={dragStart:function(t){t=t.dragEl;oe=t},dragOverValid:function(t){var e=t.completed,n=t.target,o=t.onMove,i=t.activeSortable,r=t.changed,a=t.cancel;i.options.swap&&(t=this.sortable.el,i=this.options,n&&n!==t&&(t=oe,oe=!1!==o(n)?(k(n,i.swapClass,!0),n):null,t&&t!==oe&&k(t,i.swapClass,!1)),r(),e(!0),a())},drop:function(t){var e,n,o=t.activeSortable,i=t.putSortable,r=t.dragEl,a=i||this.sortable,l=this.options;oe&&k(oe,l.swapClass,!1),oe&&(l.swap||i&&i.options.swap)&&r!==oe&&(a.captureAnimationState(),a!==o&&o.captureAnimationState(),n=oe,t=(e=r).parentNode,l=n.parentNode,t&&l&&!t.isEqualNode(n)&&!l.isEqualNode(e)&&(i=j(e),r=j(n),t.isEqualNode(l)&&i<r&&r++,t.insertBefore(n,t.children[i]),l.insertBefore(e,l.children[r])),a.animateAll(),a!==o&&o.animateAll())},nulling:function(){oe=null}},a(t,{pluginName:"swap",eventProperties:function(){return{swapItem:oe}}})}),Ht.mount(new function(){function t(o){for(var t in this)"_"===t.charAt(0)&&"function"==typeof this[t]&&(this[t]=this[t].bind(this));o.options.avoidImplicitDeselect||(o.options.supportPointer?f(document,"pointerup",this._deselectMultiDrag):(f(document,"mouseup",this._deselectMultiDrag),f(document,"touchend",this._deselectMultiDrag))),f(document,"keydown",this._checkKeyDown),f(document,"keyup",this._checkKeyUp),this.defaults={selectedClass:"sortable-selected",multiDragKey:null,avoidImplicitDeselect:!1,setData:function(t,e){var n="";he.length&&se===o?he.forEach(function(t,e){n+=(e?", ":"")+t.textContent}):n=e.textContent,t.setData("Text",n)}}}return t.prototype={multiDragKeyDown:!1,isMultiDrag:!1,delayStartGlobal:function(t){t=t.dragEl;ce=t},delayEnded:function(){this.isMultiDrag=~he.indexOf(ce)},setupClone:function(t){var e=t.sortable,t=t.cancel;if(this.isMultiDrag){for(var n=0;n<he.length;n++)fe.push(T(he[n])),fe[n].sortableIndex=he[n].sortableIndex,fe[n].draggable=!1,fe[n].style["will-change"]="",k(fe[n],this.options.selectedClass,!1),he[n]===ce&&k(fe[n],this.options.chosenClass,!1);e._hideClone(),t()}},clone:function(t){var e=t.sortable,n=t.rootEl,o=t.dispatchSortableEvent,t=t.cancel;this.isMultiDrag&&(this.options.removeCloneOnHide||he.length&&se===e&&(ve(!0,n),o("clone"),t()))},showClone:function(t){var e=t.cloneNowShown,n=t.rootEl,t=t.cancel;this.isMultiDrag&&(ve(!1,n),fe.forEach(function(t){R(t,"display","")}),e(),de=!1,t())},hideClone:function(t){var e=this,n=(t.sortable,t.cloneNowHidden),t=t.cancel;this.isMultiDrag&&(fe.forEach(function(t){R(t,"display","none"),e.options.removeCloneOnHide&&t.parentNode&&t.parentNode.removeChild(t)}),n(),de=!0,t())},dragStartGlobal:function(t){t.sortable;!this.isMultiDrag&&se&&se.multiDrag._deselectMultiDrag(),he.forEach(function(t){t.sortableIndex=j(t)}),he=he.sort(function(t,e){return t.sortableIndex-e.sortableIndex}),me=!0},dragStarted:function(t){var e,n=this,t=t.sortable;this.isMultiDrag&&(this.options.sort&&(t.captureAnimationState(),this.options.animation&&(he.forEach(function(t){t!==ce&&R(t,"position","absolute")}),e=X(ce,!1,!0,!0),he.forEach(function(t){t!==ce&&x(t,e)}),pe=ge=!0)),t.animateAll(function(){pe=ge=!1,n.options.animation&&he.forEach(function(t){A(t)}),n.options.sort&&be()}))},dragOver:function(t){var e=t.target,n=t.completed,t=t.cancel;ge&&~he.indexOf(e)&&(n(!1),t())},revert:function(t){var n,o,e=t.fromSortable,i=t.rootEl,r=t.sortable,a=t.dragRect;1<he.length&&(he.forEach(function(t){r.addAnimationState({target:t,rect:ge?X(t):a}),A(t),t.fromRect=a,e.removeAnimationState(t)}),ge=!1,n=!this.options.removeCloneOnHide,o=i,he.forEach(function(t,e){e=o.children[t.sortableIndex+(n?Number(e):0)];e?o.insertBefore(t,e):o.appendChild(t)}))},dragOverCompleted:function(t){var e,n=t.sortable,o=t.isOwner,i=t.insertion,r=t.activeSortable,a=t.parentEl,l=t.putSortable,t=this.options;i&&(o&&r._hideClone(),pe=!1,t.animation&&1<he.length&&(ge||!o&&!r.options.sort&&!l)&&(e=X(ce,!1,!0,!0),he.forEach(function(t){t!==ce&&(x(t,e),a.appendChild(t))}),ge=!0),o||(ge||be(),1<he.length?(o=de,r._showClone(n),r.options.animation&&!de&&o&&fe.forEach(function(t){r.addAnimationState({target:t,rect:ue}),t.fromRect=ue,t.thisAnimationDuration=null})):r._showClone(n)))},dragOverAnimationCapture:function(t){var e=t.dragRect,n=t.isOwner,t=t.activeSortable;he.forEach(function(t){t.thisAnimationDuration=null}),t.options.animation&&!n&&t.multiDrag.isMultiDrag&&(ue=a({},e),e=D(ce,!0),ue.top-=e.f,ue.left-=e.e)},dragOverAnimationComplete:function(){ge&&(ge=!1,be())},drop:function(t){var o,i,r,a,n,e,l,s=t.originalEvent,c=t.rootEl,u=t.parentEl,d=t.sortable,h=t.dispatchSortableEvent,f=t.oldIndex,t=t.putSortable,p=t||this.sortable;s&&(o=this.options,i=u.children,me||(o.multiDragKey&&!this.multiDragKeyDown&&this._deselectMultiDrag(),k(ce,o.selectedClass,!~he.indexOf(ce)),~he.indexOf(ce)?(he.splice(he.indexOf(ce),1),le=null,U({sortable:d,rootEl:c,name:"deselect",targetEl:ce,originalEvent:s})):(he.push(ce),U({sortable:d,rootEl:c,name:"select",targetEl:ce,originalEvent:s}),s.shiftKey&&le&&d.el.contains(le)?(r=j(le),a=j(ce),~r&&~a&&r!==a&&function(){for(var e,t=r<a?(e=r,a):(e=a,r+1),n=o.filter;e<t;e++)~he.indexOf(i[e])||P(i[e],o.draggable,u,!1)&&(n&&("function"==typeof n?n.call(d,s,i[e],d):n.split(",").some(function(t){return P(i[e],t.trim(),u,!1)}))||(k(i[e],o.selectedClass,!0),he.push(i[e]),U({sortable:d,rootEl:c,name:"select",targetEl:i[e],originalEvent:s})))}()):le=ce,se=p)),me&&this.isMultiDrag&&(ge=!1,(u[K].options.sort||u!==c)&&1<he.length&&(n=X(ce),e=j(ce,":not(."+this.options.selectedClass+")"),!pe&&o.animation&&(ce.thisAnimationDuration=null),p.captureAnimationState(),pe||(o.animation&&(ce.fromRect=n,he.forEach(function(t){var e;t.thisAnimationDuration=null,t!==ce&&(e=ge?X(t):n,t.fromRect=e,p.addAnimationState({target:t,rect:e}))})),be(),he.forEach(function(t){i[e]?u.insertBefore(t,i[e]):u.appendChild(t),e++}),f===j(ce)&&(l=!1,he.forEach(function(t){t.sortableIndex!==j(t)&&(l=!0)}),l&&(h("update"),h("sort")))),he.forEach(function(t){A(t)}),p.animateAll()),se=p),(c===u||t&&"clone"!==t.lastPutMode)&&fe.forEach(function(t){t.parentNode&&t.parentNode.removeChild(t)}))},nullingGlobal:function(){this.isMultiDrag=me=!1,fe.length=0},destroyGlobal:function(){this._deselectMultiDrag(),p(document,"pointerup",this._deselectMultiDrag),p(document,"mouseup",this._deselectMultiDrag),p(document,"touchend",this._deselectMultiDrag),p(document,"keydown",this._checkKeyDown),p(document,"keyup",this._checkKeyUp)},_deselectMultiDrag:function(t){if(!(void 0!==me&&me||se!==this.sortable||t&&P(t.target,this.options.draggable,this.sortable.el,!1)||t&&0!==t.button))for(;he.length;){var e=he[0];k(e,this.options.selectedClass,!1),he.shift(),U({sortable:this.sortable,rootEl:this.sortable.el,name:"deselect",targetEl:e,originalEvent:t})}},_checkKeyDown:function(t){t.key===this.options.multiDragKey&&(this.multiDragKeyDown=!0)},_checkKeyUp:function(t){t.key===this.options.multiDragKey&&(this.multiDragKeyDown=!1)}},a(t,{pluginName:"multiDrag",utils:{select:function(t){var e=t.parentNode[K];e&&e.options.multiDrag&&!~he.indexOf(t)&&(se&&se!==e&&(se.multiDrag._deselectMultiDrag(),se=e),k(t,e.options.selectedClass,!0),he.push(t))},deselect:function(t){var e=t.parentNode[K],n=he.indexOf(t);e&&e.options.multiDrag&&~n&&(k(t,e.options.selectedClass,!1),he.splice(n,1))}},eventProperties:function(){var n=this,o=[],i=[];return he.forEach(function(t){var e;o.push({multiDragElement:t,index:t.sortableIndex}),e=ge&&t!==ce?-1:ge?j(t,":not(."+n.options.selectedClass+")"):j(t),i.push({multiDragElement:t,index:e})}),{items:e(he),clones:[].concat(fe),oldIndicies:o,newIndicies:i}},optionListeners:{multiDragKey:function(t){return"ctrl"===(t=t.toLowerCase())?t="Control":1<t.length&&(t=t.charAt(0).toUpperCase()+t.substr(1)),t}}})}),Ht});
33143 33144 33145; 33146////pf: masters/themes/grit/program-list/program-list.ts 33147// @ts-nocheck 33148 33149/** 33150 * Get a query parameter from the URL 33151 * @param {string} parameter - The parameter name to retrieve 33152 * @returns {string|null} - The parameter value or null 33153 */ 33154function getQueryString(parameter) { 33155 const params = new URLSearchParams(window.location.search); 33156 return params.get(parameter); 33157} 33158 33159/** 33160 * Parse comma-separated values from a query string into an array 33161 * @param {string} value - The query string value 33162 * @returns {string[]} - Array of values 33163 */ 33164function parseMultiValue(value) { 33165 if (!value) return []; 33166 return value 33167 .split(",") 33168 .map((v) => decodeURIComponent(v.trim())) 33169 .filter(Boolean); 33170} 33171 33172/** 33173 * Convert array to comma-separated string 33174 * @param {string[]} values - Array of values 33175 * @returns {string} - Comma-separated string 33176 */ 33177function stringifyMultiValue(values) { 33178 if (!values || !values.length) return ""; 33179 return values.join(","); 33180} 33181 33182let waypoints = []; 33183function setWaypoints() { 33184 // @ts-expect-error dont worry about it 33185 waypoints.forEach((wp) => wp.destroy()); 33186 waypoints = []; 33187 $(".program-list li:visible, .program-list-results li:visible").each( 33188 function () { 33189 $(this).addClass("fade-in-on-view"); 33190 33191 // @ts-expect-error it's fine 33192 const wp = new Waypoint({ 33193 element: this, 33194 offset: "95%", 33195 handler: (direction) => { 33196 $(this).toggleClass("in-view", direction === "down"); 33197 }, 33198 }); 33199 waypoints.push(wp); 33200 } 33201 ); 33202} 33203 33204function getFilterOption($element, value) { 33205 return $element.find(`input[value="${value}"]`).parent(); 33206} 33207 33208function setUpProgramFilters() { 33209 setWaypoints(); 33210 const DEFAULT = "Any"; 33211 const originalSearch = window.location.search.replace("?", ""); 33212 const $filterButtons = $("button[filter-key]");
33213 const $programs = $(".program-list li, .program-list-results li"); 33214 33215 const filterConfigs = $filterButtons 33216 .map(function () { 33217 const $button = $(this); 33218 const modalId = $button.attr("filter-modal"); 33219 const label = $button.attr("filter-label"); 33220 const key = $button.attr("filter-key"); 33221 return { 33222 $button, 33223 key, 33224 label, 33225 modalId, 33226 programFilterData: $button.attr("program-data"), 33227 modal: $.fn.gritModal({ 33228 target: modalId, 33229 title: label, 33230 onSubmit: () => { 33231 filters[key] = tempFilters[key]; 33232 filterAndUpdateUrl(); 33233 }, 33234 submitText: '<i class="fa fa-check"></i> Apply', 33235 onClose: ($modalElement) => { 33236 setSelectedModalOptions(filters[key], $modalElement); 33237 }, 33238 }), 33239 }; 33240 }) 33241 .get(); 33242 33243 const filters = filterConfigs.reduce((acc, config) => { 33244 if (!config.key) throw new Error("Missing filter key"); 33245 const values = parseMultiValue(getQueryString(config.key)); 33246 acc[config.key] = values.includes(DEFAULT) ? [] : values; 33247 return acc; 33248 }, {}); 33249 const tempFilters = {}; 33250 33251 function updateResetButton() { 33252 const searchValue = $("#program-search").val(); 33253 const hasFiltering = 33254 !!searchValue || Object.values(filters).some((arr) => arr.length > 0); 33255 $("#reset-filters").prop("disabled", !hasFiltering); 33256 } 33257 33258 function updateFilterButtons() { 33259 filterConfigs.forEach((config) => { 33260 if (!config.key) throw new Error("Missing filter key"); 33261 const values = filters[config.key]; 33262 const { $button } = config; 33263 const selectedLabels = []; 33264 33265 if (values && values.length) { 33266 values.forEach((value) => { 33267 const $option = getFilterOption(config.modal.$element, value); 33268 if ($option.length) { 33269 const label = $option.text().trim(); 33270 if (label && label !== DEFAULT) { 33271 selectedLabels.push(label); 33272 } 33273 } 33274 }); 33275 } 33276 33277 let buttonText; 33278 if (selectedLabels.length === 0) { 33279 buttonText = config.label; 33280 } else if (selectedLabels.length === 1) { 33281 buttonText = selectedLabels[0]; 33282 } else { 33283 buttonText = `${selectedLabels[0]} +${selectedLabels.length - 1}`; 33284 } 33285 33286 $button 33287 .text(buttonText) 33288 .toggleClass("selected", selectedLabels.length > 0); 33289 }); 33290 } 33291 33292 function setSelectedModalOptions(filterValues, $modalElement) { 33293 const $defaultOption = getFilterOption($modalElement, DEFAULT); 33294 $modalElement.find(`[filter-option]`).each(function () { 33295 $(this).removeClass("selected"); 33296 $(this).find("input").prop("checked", false); 33297 }); 33298 if (filterValues.length) { 33299 $defaultOption.removeClass("selected"); 33300 $defaultOption.find("input").prop("checked", false); 33301 filterValues.forEach((val) => { 33302 const $option = getFilterOption($modalElement, val); 33303 $option.addClass("selected"); 33304 $option.find("input").prop("checked", true); 33305 }); 33306 } else { 33307 $defaultOption.addClass("selected"); 33308 $defaultOption.find("input").prop("checked", true); 33309 } 33310 } 33311 33312 function updateFilterValue(filtersToUpdate, key, value) { 33313 const isDefault = value === DEFAULT || !value; 33314 33315 if (isDefault) { 33316 filtersToUpdate[key] = []; 33317 } else { 33318 const valueIndex = filtersToUpdate[key].indexOf(value); 33319 if (valueIndex === -1) { 33320 filtersToUpdate[key].push(value); 33321 } else { 33322 filtersToUpdate[key].splice(valueIndex, 1); 33323 } 33324 } 33325 } 33326 33327 function getChipKeyAndValue(chip) { 33328 const arr = $(chip).attr("data-chip-filter").split("-"); 33329 const key = arr[0]; 33330 const value = arr.slice(1).join("-"); 33331 return [key, value]; 33332 } 33333 function updateChipStates() { 33334 $("[data-chip-filter]").each(function () { 33335 const [key, value] = getChipKeyAndValue(this); 33336 const isSelected = filters[key].includes(value); 33337 $(this).toggleClass("selected", isSelected); 33338 });
33339 } 33340 function attachChipClickHandlers() { 33341 $("[data-chip-filter]").on("click", function (e) { 33342 e.stopPropagation(); 33343 const [key, value] = getChipKeyAndValue(this); 33344 updateFilterValue(filters, key, value); 33345 updateChipStates(); 33346 filterAndUpdateUrl(); 33347 }); 33348 33349 $(".program-tags .chip:not([data-chip-filter])").on("click", function (e) { 33350 e.stopPropagation(); 33351 }); 33352 } 33353 33354 function attachProgramItemClickHandlers() { 33355 $(".program-item").on("click", function (e) { 33356 const $learnMore = $(this).find(".program-details-btn"); 33357 const url = $learnMore.attr("href"); 33358 33359 if (url) { 33360 window.location.href = url; 33361 } 33362 }); 33363 33364 // Prevent links and buttons inside program items from triggering the program item click 33365 $(".program-item a, .program-item button").on("click", function (e) { 33366 e.stopPropagation(); 33367 }); 33368 } 33369 33370 function initFilterButtons() { 33371 attachChipClickHandlers(); 33372 attachProgramItemClickHandlers(); 33373 filterConfigs.forEach(function (config) { 33374 const { $button } = config; 33375 const { modalId, key } = config; 33376 if (!modalId || !key) throw new Error("Missing filter config values"); 33377 33378 $button.on("click", () => { 33379 tempFilters[key] = [...filters[key]]; 33380 setSelectedModalOptions(tempFilters[key], config.modal.$element); 33381 config.modal.open(); 33382 }); 33383 33384 // Set up filter click handlers 33385 config.modal.$element 33386 .find(`[filter-option] > input`) 33387 .on("click", function () { 33388 const value = $(this).attr("value"); 33389 updateFilterValue(tempFilters, key, value); 33390 33391 setSelectedModalOptions(tempFilters[key], config.modal.$element); 33392 }); 33393 33394 setSelectedModalOptions(filters[key], config.modal.$element); 33395 }); 33396 33397 filter(); 33398 } 33399 33400 function filterAndUpdateUrl() { 33401 filter(); 33402 setUrlQuery(); 33403 } 33404 33405 function updateTotalResults() { 33406 const totalResults = $( 33407 ".program-list li:visible, .program-list-results li:visible" 33408 ).length; 33409 $(".program-results-count").text(`${totalResults} Results`); 33410 $("#program-no-results").toggle(totalResults === 0); 33411 } 33412 33413 function filter() { 33414 updateFilterButtons(); 33415 updateChipStates(); 33416 filterConfigs.forEach((config) => { 33417 if (config.modal.isOpen()) { 33418 config.modal.close(); 33419 } 33420 }); 33421 33422 $programs.each(function () { 33423 const $item = $(this); 33424 const itemData = filterConfigs.reduce((acc, config) => { 33425 if (!config.programFilterData) 33426 throw new Error("Missing program filter data"); 33427 if (!config.key) throw new Error("Missing filter key"); 33428 const programData = $item.attr(config.programFilterData); 33429 const arrayProgramDataKeys = ["season", "gender", "region"]; 33430 acc[config.key] = arrayProgramDataKeys.includes(config.key) 33431 ? programData?.split(", ") || [] 33432 : [programData]; 33433 return acc; 33434 }, {}); 33435 33436 const query = $("#program-search").val(); 33437 const programTitle = $item.find("#ProgramTitle").text(); 33438 33439 let isVisible = true; 33440 if (query) { 33441 isVisible = programTitle.toLowerCase().includes(query.toLowerCase()); 33442 } 33443 if (isVisible) { 33444 isVisible = Object.entries(filters).every(([key, values]) => { 33445 const itemValue = itemData[key]; 33446 return ( 33447 values.length === 0 || values.some((v) => itemValue.includes(v)) 33448 ); 33449 }); 33450 } 33451 33452 $item.toggle(isVisible); 33453 }); 33454 33455 updateTotalResults(); 33456 updateResetButton(); 33457 setWaypoints(); 33458 } 33459 $("#program-search").on("input", filter); 33460 33461 function setUrlQuery() { 33462 const url = new URL(window.location.href.split("?")[0]); 33463 const params = new URLSearchParams(); 33464 33465 // Preserve non-filter params from original URL 33466 const originalParams = new URLSearchParams(originalSearch); 33467 Array.from(originalParams.keys()) 33468 .filter( 33469 (key) => !["gender", "season", "region", "type", "state"].includes(key) 33470 ) 33471 .forEach((key) => { 33472 const value = originalParams.get(key); 33473 if (value) params.set(key, value); 33474 }); 33475
33476 Object.entries(filters).forEach(([key, values]) => { 33477 if (values.length > 0) { 33478 params.set(key, stringifyMultiValue(values)); 33479 } 33480 }); 33481 33482 const queryString = params.toString() ? `?${params.toString()}` : ""; 33483 history.pushState({}, document.title, url.pathname + queryString); 33484 } 33485 33486 function resetFilters() { 33487 Object.keys(filters).forEach((key) => (filters[key] = [])); 33488 33489 // Reset UI states 33490 filterConfigs.forEach(({ key, $button, label, modal }) => { 33491 if (!$button || !modal || !label || !key) 33492 throw new Error("Missing filter config values"); 33493 $button.text(label).removeClass("selected"); 33494 setSelectedModalOptions(filters[key], modal.$element); 33495 }); 33496 33497 // Clear search 33498 $("#program-search").val(""); 33499 33500 filterAndUpdateUrl(); 33501 } 33502 33503 $("[data-reset-filters]").on("click", resetFilters); 33504 33505 // Handle browser back/forward navigation 33506 window.addEventListener("popstate", () => { 33507 Object.keys(filters).forEach((key) => { 33508 filters[key] = parseMultiValue(getQueryString(key)); 33509 }); 33510 33511 filter(); 33512 }); 33513 33514 // init 33515 initFilterButtons(); 33516} 33517 33518 33519; 33520////pf: masters/themes/grit/modal/modal.ts 33521$.fn.gritModal = function (config) { 33522 if (!config.target) {
33523 throw new Error("Must provide target id or content string for modal!"); 33524 } 33525 const $content = $(config.target); 33526 if (!$content.length) { 33527 throw new Error("Invalid target id or content string for modal!"); 33528 } 33529 const $placeholder = $( 33530 '<span class="grit-modal-placeholder" style="display:none"></span>' 33531 ); 33532 $content.after($placeholder); 33533 const $detached = $content.detach(); 33534 33535 const $modalRoot = $(`<div class="grit-modal-root"> 33536 <div class="grit-modal-backdrop"></div> 33537 <div class="grit-modal-container"> 33538 <div class="grit-modal-wrapper"> 33539 <div class="grit-modal ${config.modalClass}"> 33540 ${ 33541 config.title 33542 ? `<div class="grit-modal-title"> 33543 <h2 class="h2">${config.title}</h2> 33544 <button type="button" class="grit-icon-button sm secondary outlined" grit-modal-close> 33545 <i class="fa fa-xmark"></i> 33546 </button> 33547 </div>` 33548 : `<button type="button" class="grit-icon-button sm secondary outlined no-title-close" grit-modal-close> 33549 <i class="fa fa-xmark"></i> 33550 </button>` 33551 } 33552 <div class="grit-modal-content"> 33553 </div> 33554 </div> 33555 </div> 33556 </div>`); 33557 33558 $modalRoot.find(".grit-modal-content").append($detached); 33559 33560 if ($detached.css("display") === "none") { 33561 $detached.css("display", ""); 33562 } 33563 33564 const getIsMobile = () => { 33565 return window.innerWidth < 870; 33566 }; 33567 const duration = 300; 33568 const $modalElementWrapper = $modalRoot.find(".grit-modal-wrapper"); 33569 const handleOpen = () => { 33570 $("html").css("overflow", "hidden"); 33571 $(config.anchor || "body").append($modalRoot); 33572 function doOpen() { 33573 config.onOpen?.($modalRoot); 33574 } 33575 if (getIsMobile()) { 33576 $modalElementWrapper.slideToggle(duration, doOpen); 33577 } else { 33578 $modalElementWrapper.fadeIn(duration, doOpen); 33579 } 33580 }; 33581 const handleClose = () => { 33582 $("html").css("overflow", ""); 33583 function doClose() { 33584 const $detached = $modalRoot.detach(); 33585 33586 const $contentInModal = $($detached.find(".grit-modal-content").html()); 33587 $placeholder.before($contentInModal); 33588 $placeholder.remove(); 33589 $contentInModal.css("display", "none"); 33590 33591 config.onClose?.($detached); 33592 } 33593 if (getIsMobile()) { 33594 $modalElementWrapper.slideToggle(duration, doClose); 33595 } else { 33596 $modalElementWrapper.fadeOut(duration, doClose); 33597 } 33598 }; 33599 33600 $modalRoot.find("[grit-modal-close]").on("click", handleClose); 33601 const $modalElement = $modalRoot.find(".grit-modal"); 33602 33603 let $submitButton; 33604 if (config.onSubmit) { 33605 $submitButton = 33606 $(`<button type="button" grit-modal-submit class="grit-button contained primary"> 33607 ${config.submitText || "Submit"} 33608 </button>`); 33609 $submitButton.on("click", config.onSubmit); 33610 33611 const $cancelButton = 33612 $(`<button type="button" grit-modal-cancel class="grit-button outlined secondary"> 33613 ${config.cancelText || "Cancel"} 33614 </button>`); 33615 $cancelButton.on("click", handleClose); 33616 const $modalFooter = $("<div class='grit-modal-footer'></div>"); 33617 $modalFooter.append($cancelButton); 33618 $modalFooter.append($submitButton); 33619 $modalElement.append($modalFooter); 33620 } 33621 33622 const modal = { 33623 $element: $modalRoot, 33624 open: function () { 33625 handleOpen(); 33626 return this; 33627 }, 33628 close: handleClose, 33629 isOpen: function () { 33630 return $modalRoot.is(":visible"); 33631 }, 33632 setSubmitButtonState: function (state) { 33633 if ($submitButton) { 33634 if (state.className) { 33635 if (typeof state.className === "string") { 33636 $submitButton.removeClass().addClass(state.className); 33637 } else { 33638 const existingClassName = $submitButton.attr("class") || ""; 33639 $submitButton 33640 .removeClass() 33641 .addClass(state.className(existingClassName)); 33642 } 33643 } 33644 if (state.text) $submitButton.html(state.text); 33645 $submitButton.prop("disabled", state.disabled); 33646 } 33647 }, 33648 }; 33649 33650 $modalRoot.find(".grit-modal-container").on("click", function (e) { 33651 if (e.target === this && modal.isOpen()) { 33652 modal.close(); 33653 } 33654 }); 33655 33656 $(document).on("keydown", function (e) { 33657 if (e.key === "Escape" && modal.isOpen()) { 33658 modal.close(); 33659 } 33660 }); 33661 33662 return modal; 33663}; 33664 33665$.fn.openGritModal = function (config) { 33666 return $.fn.gritModal(config).open(); 33667}; 33668 33669 33670; 33671////pf: masters/themes/grit/register/register.ts 33672let programName = ""; 33673 33674function initRegistrationHandlers() { 33675 programName = $("#HeadingLabel").text(); 33676 33677 $("#MainRegisterButton").on("click", function () { 33678 if ($("#PasscodeDialog").length) { 33679 openPasscodeModal(); 33680 } else { 33681 openRegistrationModal(); 33682 } 33683 }); 33684 33685 function openPasscodeModal() { 33686 const passcodeModal = $.fn.openGritModal({ 33687 target: "#PasscodeDialog", 33688 title: programName, 33689 onOpen: ($element) => { 33690 const $pcInput = $element.find("[id$=_ProgramPassCode]"); 33691 $pcInput.trigger("focus"); 33692 }, 33693 onClose: ($modalElement) => { 33694 const $pcInput = $modalElement.find("[id$=_ProgramPassCode]"); 33695 $pcInput.val(""); 33696 }, 33697 });
33698 const $pcElement = passcodeModal.$element; 33699 const $pcInput = $pcElement.find("[id$=_ProgramPassCode]"); 33700 const $pcButton = $pcElement.find("#PassCodeModalEnter"); 33701 const $errorDialog = $pcElement.find("#PasscodeErrorDialog"); 33702 33703 $pcInput.on("input", function () { 33704 const value = $(this).val(); 33705 // @ts-expect-error value will be string 33706 if (value?.length) { 33707 $pcButton.prop("disabled", false); 33708 } else { 33709 $pcButton.prop("disabled", true); 33710 } 33711 }); 33712 33713 $pcButton.on("click", async function () { 33714 $errorDialog.toggle(false); 33715 const passCode = $pcElement.find("[id$=_ProgramPassCode]").val(); 33716 const programId = $("#HiddenProgramId").val(); 33717 33718 if (!passCode) { 33719 $errorDialog.toggle(true); 33720 return; 33721 } 33722 33723 try { 33724 $(this).prop("disabled", true); 33725 $(this).prepend('<i class="fa fa-spinner fa-spin"></i>'); 33726 const res = await fetch( 33727 `/api/program/${programId}/validate-passcode/${passCode}`, 33728 { 33729 method: "POST", 33730 headers: { 33731 "Content-Type": "application/json", 33732 }, 33733 } 33734 ); 33735 33736 if (res.ok) { 33737 $pcElement.find("#PasscodeConfirmDialog").toggle(true); 33738 $pcElement.find("#PasscodeEntry").toggle(false); 33739 window.location.replace( 33740 window.location + `&passCode=${passCode}&openRegisterDialog=true` 33741 ); 33742 } else { 33743 $errorDialog.toggle(true); 33744 } 33745 } catch (err) { 33746 $errorDialog.toggle(true); 33747 } finally { 33748 $(this).prop("disabled", false); 33749 $(this).find("i").remove(); 33750 } 33751 33752 return false; 33753 }); 33754 } 33755 33756} 33757 33758function openRegistrationModal(options = {}) { 33759 const regModal = $.fn.openGritModal({ 33760 target: "#RegistrationOptionsModal", 33761 title: programName, 33762 modalClass: "lg", 33763 ...options, 33764 }); 33765 33766 const $modalElement = regModal.$element; 33767 const $regOptionsList = $modalElement.find("#RegOptionsList"); 33768 const $regOptionsTitle = $modalElement.find("#RegOptionsTitle"); 33769 const selected = []; 33770 33771 const updateStyles = () => { 33772 if ($modalElement.find("li[data-no-levels]").length) { 33773 $regOptionsTitle.text("Registration Options"); 33774 } else if (!selected.length) { 33775 $regOptionsTitle.text("Select an option:"); 33776 } 33777 33778 let $ul = $regOptionsList; 33779 for (let level = 0; level < 3; level++) { 33780 $ul.find("> li").toggle(selected.length <= level); 33781 $ul.find("> li > .DivisionSelectionDetails").toggle(false); 33782 $ul.find("> li > .DivisionMainDivisionButton").toggle(true); 33783 33784 if (selected.length > level) { 33785 $ul.find("> li").eq(selected[level]).toggle(true); 33786 $ul.find("> li > .DivisionMainDivisionButton").toggle(false); 33787 const $details = $ul 33788 .find("> li") 33789 .eq(selected[level]) 33790 .find("> .DivisionSelectionDetails"); 33791 $details.toggle(true); 33792 $regOptionsTitle.text(`Register for ${$details.data("label")}`); 33793 $ul = $ul 33794 .find("> li") 33795 .eq(selected[level]) 33796 .find(`ul[data-level=${level + 1}]`); 33797 } else { 33798 $ul = $ul.find(`ul[data-level=${level + 1}]`); 33799 } 33800 } 33801 $modalElement 33802 .find(".DivisionSelectionDetailsBackButton") 33803 .toggle(selected.length > 0); 33804 }; 33805 33806 $modalElement.find(".DivisionMainDivisionButton").on("click", function () { 33807 selected.push( 33808 // @ts-expect-error its fine 33809 $(this).closest("ul").find("> li").index($(this).closest("li")) 33810 ); 33811 updateStyles(); 33812 return false; 33813 }); 33814 33815 $(".DivisionSelectionDetailsBackButton").on("click", function () { 33816 selected.pop(); 33817 updateStyles(); 33818 return false; 33819 }); 33820 33821 if ($(".ExpandoBoxes > li").length === 1 && !$modalElement.find("li[data-no-levels]").length) { 33822 // @ts-expect-error really need to make these modules so I can type them 33823 selected.push(0); 33824 } 33825 33826 updateStyles(); 33827} 33828 33829 33830; 33831////pf: masters/themes/grit/carousel/carousel.ts 33832function initCarousels() { 33833 const carouselElements = $("[data-slick]");
33834 carouselElements.each(function () { 33835 const $this = $(this); 33836 if (!$this.is(":hidden") && !$this.hasClass("slick-initialized")) { 33837 $this.slick(); 33838 } 33839 }); 33840} 33841 33842$(function () { 33843 initCarousels(); 33844}); 33845 33846 33847; 33848////pf: javascript/page-templates.js 33849let templateModal 33850const config = { 33851 target: "#AddTemplateModal", 33852 title: "Create New Page Template", 33853 onClose: resetForm, 33854 onSubmit: handleTemplateSubmit, 33855 submitText: "Create Template", 33856 anchor: "#modal-anchor", 33857}; 33858let categoriesLoaded = false; 33859 33860function openAddTemplateModal() { 33861 if (templateModal) templateModal.open(); 33862 else { 33863 templateModal = $.fn.openGritModal(config); 33864 } 33865} 33866 33867function resetForm() { 33868 $("#form-errors").hide(); 33869 $("#template-title").val(""); 33870 $("#CategoryDropDown").val(""); 33871 $("#TemplateAffiliation").val("current"); 33872 resetSubmitState(); 33873} 33874 33875function handleTemplateSubmit() { 33876 const title = $("#template-title").val()?.trim() ?? ""; 33877 const categoryId = $("#CategoryDropDown").val(); 33878 const affiliation = $("#TemplateAffiliation").val(); 33879 33880 const errors = []; 33881 $("#form-errors").empty(); 33882 $("#form-errors").hide(); 33883 if (!title) { 33884 errors.push("Title is required."); 33885 } else if (title.length > 255) { 33886 errors.push("Title must be 255 characters or less."); 33887 } 33888 if (!categoryId) { 33889 errors.push("Category is required."); 33890 } 33891 33892 if (errors.length) { 33893 $("#form-errors").text(errors.join("\n")).show(); 33894 return false; 33895 } 33896 33897 templateModal.setSubmitButtonState({ 33898 disabled: true, 33899 text: "<i class='fa fa-spinner fa-spin'></i> Creating...", 33900 }); 33901 33902 $.ajax({ 33903 url: window.location.href, 33904 type: "POST", 33905 headers: { 33906 "X-Requested-With": "XMLHttpRequest", 33907 }, 33908 data: { 33909 title: title, 33910 categoryId: categoryId, 33911 affiliation: affiliation, 33912 }, 33913 success: function (response) { 33914 if (response.success) { 33915 window.location.href = response.redirectUrl; 33916 } else { 33917 showGeneralError(response.error || "Unknown error occurred"); 33918 resetSubmitState(); 33919 } 33920 }, 33921 error: function (xhr) { 33922 let errorMessage = "An error occurred while creating the template"; 33923 try { 33924 const errorResponse = JSON.parse(xhr.responseText); 33925 errorMessage = errorResponse.error || errorMessage; 33926 } catch (e) { 33927 console.error('Error parsing response:', e); 33928 } 33929 33930 showGeneralError(errorMessage); 33931 resetSubmitState(); 33932 }, 33933 }); 33934 33935 return false; 33936} 33937 33938function showFieldError(errorId, message) { 33939 $(`#${errorId}`).text(message).show(); 33940} 33941 33942function showGeneralError(message) { 33943 alert(message); // TODO: better UI 33944} 33945 33946function resetSubmitState() { 33947 templateModal.setSubmitButtonState({ 33948 disabled: false, 33949 text: "Create Template", 33950 }); 33951} 33952 33953 33954; 33955////pf: masters/themes/grit/sortable-list/sortable-list.js 33956window.GritSortableList = (function () { 33957 const instances = new WeakMap(); 33958 33959 function resolveElement(target) { 33960 if (!target) return null; 33961 if (typeof target === "string") return document.querySelector(target); 33962 return target; 33963 } 33964 33965 function getItems(container, itemSelector) { 33966 return Array.from(container.querySelectorAll(itemSelector)); 33967 } 33968 33969 function notifyReorder(state, item) { 33970 if (!state?.onReorder) return; 33971 const items = getItems(state.container, state.itemSelector); 33972 state.onReorder({ 33973 item, 33974 items, 33975 index: items.indexOf(item), 33976 }); 33977 } 33978 33979 function canDragItem(item, canDragAttr) { 33980 if (!canDragAttr) return true; 33981 const value = item.getAttribute(canDragAttr); 33982 return value === null || value === "true"; 33983 } 33984 33985 function init(options) { 33986 const container = resolveElement(options.container); 33987 if (!container) return null; 33988 33989 const itemSelector = options.itemSelector || "[data-sortable-item]"; 33990 const handleSelector = options.handleSelector || null; 33991 const canDragAttr = 33992 options.canDragAttr === undefined ? "data-can-drag" : options.canDragAttr; 33993 const draggingClass = options.draggingClass || "dragging"; 33994 const scrollContainer = resolveElement(options.scrollContainer); 33995 const onReorder = options.onReorder; 33996 33997 instances.get(container)?.sortable?.destroy(); 33998 33999 const state = { 34000 container, 34001 itemSelector, 34002 onReorder, 34003 sortable: null, 34004 }; 34005 34006 const menuItems = getItems(container, itemSelector);
34007 menuItems.forEach((item) => { 34008 if (canDragItem(item, canDragAttr)) { 34009 item.setAttribute("data-sortable-item", ""); 34010 } else { 34011 item.removeAttribute("data-sortable-item"); 34012 } 34013 }); 34014 34015 if (typeof Sortable !== "undefined") { 34016 state.sortable = Sortable.create(container, { 34017 animation: 150, 34018 draggable: `${itemSelector}[data-sortable-item]`, 34019 filter: "button, a, input, select, textarea", 34020 preventOnFilter: false, 34021 ghostClass: draggingClass, 34022 handle: handleSelector || undefined, 34023 scroll: scrollContainer || true, 34024 bubbleScroll: true, 34025 onEnd: function (event) { 34026 if (event.oldDraggableIndex !== event.newDraggableIndex) { 34027 notifyReorder(state, event.item); 34028 } 34029 }, 34030 }); 34031 } 34032 34033 instances.set(container, state); 34034 return state; 34035 } 34036 34037 function moveByOffset(item, offset) { 34038 if (!item?.parentElement) return false; 34039 const state = instances.get(item.parentElement); 34040 if (!state) return false; 34041 34042 const items = getItems(state.container, state.itemSelector); 34043 const index = items.indexOf(item); 34044 const newIndex = index + offset; 34045 if (index < 0 || newIndex < 0 || newIndex >= items.length) return false; 34046 34047 const target = items[newIndex]; 34048 if (offset > 0) { 34049 target.parentNode?.insertBefore(item, target.nextSibling); 34050 } else { 34051 target.parentNode?.insertBefore(item, target); 34052 } 34053 34054 notifyReorder(state, item); 34055 return true; 34056 } 34057 34058 function moveUp(item) { 34059 return moveByOffset(item, -1); 34060 } 34061 34062 function moveDown(item) { 34063 return moveByOffset(item, 1); 34064 } 34065 34066 return { 34067 init, 34068 moveUp, 34069 moveDown, 34070 }; 34071})(); 34072 34073 34074; 34075////pf: masters/themes/grit/program-page-menu/program-page-menu.ts 34076// @ts-nocheck - remove this after bundling TS files with webpack 34077function changeElementVisibility() { 34078 const urlParams = new URLSearchParams(window.location.search); 34079 const editingParam = urlParams.get("editing"); 34080 34081 if (editingParam) { 34082 $(".ProgramPageMenu li[data-page-id]").each(function () { 34083 const $li = $(this); 34084 const editingUrl = $li.attr("data-editing-url"); 34085 34086 if (editingUrl) { 34087 $li.find("a").attr("href", editingUrl); 34088 } 34089 34090 const canDrag = $li.attr("data-can-drag") === "true"; 34091 if (canDrag) { 34092 $li.find(".drag-handle").css("display", ""); 34093 } 34094 }); 34095 34096 const addButton = document.getElementById("AddNewTabButton"); 34097 if (addButton?.style.display === "none") { 34098 addButton.style.display = ""; 34099 } 34100 } 34101} 34102 34103$(function () { 34104 window.addEventListener("startPageEditing", changeElementVisibility); 34105 window.addEventListener("startPageEditing", initializeDragAndDrop); 34106}); 34107 34108function openNewTabModal() { 34109 const eventId = getEventIdFromPage(); 34110 const affiliationId = window.affiliationId; 34111 34112 if (!eventId || !affiliationId) { 34113 console.error("Event ID or Affiliation ID not found"); 34114 return; 34115 } 34116 34117 const modal = $.fn.openGritModal({ 34118 target: "#NewTabDialog", 34119 title: "Add New Tab", 34120 submitText: "Create Tab", 34121 onOpen: ($element) => { 34122 const $titleInput = $element.find("#NewTabTitle"); 34123 $titleInput.trigger("focus"); 34124 setupRadioButtonHandlers($element); 34125 }, 34126 onClose: () => { 34127 clearForm(); 34128 }, 34129 onSubmit: async function () { 34130 await handleCreateTab(modal, eventId); 34131 }, 34132 }); 34133 34134 modal.setSubmitButtonState({ disabled: true }); 34135 setupTitleInput(modal); 34136} 34137 34138function setupTitleInput(modal) { 34139 let dirty = false; 34140 const $titleInput = modal.$element.find("#NewTabTitle"); 34141 const $errorElement = $("#NewTabTitleError"); 34142 const VALID_PATTERN = /^[A-Za-z0-9][^\\]*[^\s+\-\\]$/; 34143 34144 const getError = (value) => { 34145 if ((!value || value.length < 3) && dirty) 34146 return "Title must be at least 3 characters long."; 34147 if (!/^[A-Za-z0-9]/.test(value) || /[\s+\-\\]$/.test(value)) 34148 return "Title must not start with a special character or end with a space, +, -, or \\"; 34149 if (!VALID_PATTERN.test(value)) 34150 return "Invalid title. '\\' is not allowed."; 34151 return ""; 34152 }; 34153 34154 const isValid = (value) => value.length >= 3 && VALID_PATTERN.test(value); 34155 34156 $titleInput.on("change blur", () => { 34157 dirty = true; 34158 }); 34159 34160 $titleInput.on("input", function () {
34161 const value = String($titleInput.val() ?? "").trim(); 34162 $errorElement.text(getError(value)); 34163 modal.setSubmitButtonState({ disabled: !isValid(value) }); 34164 }); 34165} 34166 34167function setupRadioButtonHandlers($element) { 34168 const $customControl = $element.find("#CustomLinkUrlControl"); 34169 34170 $element.find("input[name='LinkingGroup']").on("change", function () { 34171 const selectedValue = $(this).val(); 34172 if (selectedValue === "custom") { 34173 $customControl.show(); 34174 } else { 34175 $customControl.hide(); 34176 $element.find("#CustomPageLinkUrl").val(""); 34177 } 34178 }); 34179} 34180 34181function clearForm() { 34182 $("#NewTabTitle").val(""); 34183 $("#ProgramPageDisplay").prop("checked", true); 34184 $("#ShareProgramPage").prop("checked", false); 34185 $("#SendNoneRadio").prop("checked", true); 34186 $("#CustomPageLinkUrl").val(""); 34187 $("#CustomLinkUrlControl").hide(); 34188} 34189 34190async function handleCreateTab(modal, eventId) { 34191 const title = $("#NewTabTitle").val().trim(); 34192 const isVisible = $("#ProgramPageDisplay").prop("checked"); 34193 const sharePage = $("#ShareProgramPage").prop("checked"); 34194 const selectedLinking = $("input[name='LinkingGroup']:checked").val(); 34195 const customUrl = $("#CustomPageLinkUrl").val().trim(); 34196 34197 if (!title || title.length < 3) { 34198 $.fn.modalAlert.open({ 34199 content: "Please enter a tab title (at least 3 characters)", 34200 }); 34201 return; 34202 } 34203 34204 if (selectedLinking === "custom" && !customUrl) { 34205 $.fn.modalAlert.open({ content: "Please enter a custom URL" }); 34206 return; 34207 } 34208 34209 let linkUrl = ""; 34210 if (selectedLinking === "custom") { 34211 linkUrl = customUrl; 34212 } else if (selectedLinking === "waiver") { 34213 linkUrl = `/my/waiver/quick?programid=${eventId}`; 34214 } else { 34215 linkUrl = ""; 34216 } 34217 34218 const requestBody = { 34219 title, 34220 isVisible, 34221 sharePage, 34222 linkUrl, 34223 }; 34224 34225 try { 34226 modal.setSubmitButtonState({ 34227 disabled: true, 34228 text: '<i class="fa fa-spinner fa-spin"></i> Creating...', 34229 }); 34230 34231 const response = await fetch(`/api/program/${eventId}/page`, { 34232 method: "POST", 34233 headers: { 34234 "Content-Type": "application/json", 34235 }, 34236 body: JSON.stringify(requestBody), 34237 }); 34238 34239 if (response.ok) { 34240 const createdPage = await response.json(); 34241 modal.close(); 34242 const params = new URLSearchParams(window.location.search); 34243 const encodedTitle = encodeURIComponent( 34244 createdPage.title.replaceAll("+", "%2b") 34245 ); 34246 params.set("PageName", encodedTitle); 34247 const url = new URL(window.location.href); 34248 url.search = params.toString(); 34249 window.location.href = url; 34250 } else { 34251 const errorText = await response.text(); 34252 console.error("Failed to create program page:", errorText); 34253 throw new Error(errorText); 34254 } 34255 } catch (error) { 34256 console.error("Error creating program page:", error); 34257 $.fn.modalAlert.open({ content: "An error occurred. Please try again." }); 34258 modal.setSubmitButtonState({ disabled: false, text: "Create Tab" }); 34259 } 34260} 34261 34262function getEventIdFromPage() { 34263 const urlParams = new URLSearchParams(window.location.search); 34264 const eventIdParam = 34265 urlParams.get("EventID") || 34266 urlParams.get("eventId") || 34267 urlParams.get("eventid"); 34268 34269 if (eventIdParam) { 34270 const eventId = parseInt(eventIdParam, 10); 34271 if (!isNaN(eventId)) { 34272 return eventId; 34273 } 34274 } 34275 34276 const hiddenField = $("#HiddenProgramId"); 34277 if (hiddenField.length) { 34278 const eventId = parseInt(hiddenField.val(), 10); 34279 if (!isNaN(eventId)) { 34280 return eventId; 34281 } 34282 } 34283 34284 return null; 34285} 34286 34287function initializeDragAndDrop() { 34288 const urlParams = new URLSearchParams(window.location.search); 34289 if (!urlParams.get("editing")) return; 34290 34291 const container = document.querySelector(".ProgramPageMenu"); 34292 if (!container || !window.GritSortableList) return; 34293 34294 const subNav = document.querySelector("#SubNav"); 34295 const scrollContainer = 34296 subNav?._scrollContainer || 34297 subNav?.querySelector(".grit-tabs-scroll-container"); 34298 34299 window.GritSortableList.init({ 34300 container, 34301 itemSelector: "li[data-page-id]", 34302 handleSelector: ".drag-handle",
34303 canDragAttr: "data-can-drag", 34304 scrollContainer, 34305 onReorder: function ({ item, items }) { 34306 const pageId = parseInt(item.getAttribute("data-page-id") || "0", 10); 34307 const newOrdinal = items.indexOf(item) + 1; 34308 window.dispatchEvent( 34309 new CustomEvent("programPageReordered", { 34310 detail: { pageId, newOrdinal }, 34311 }) 34312 ); 34313 }, 34314 }); 34315} 34316 34317 34318; 34319////pf: javascript/marketing-consent.js 34320window.MarketingConsent = window.MarketingConsent || (function () { 34321 const COOKIE_NAME = 'CookiePreferences'; 34322 const ENHANCED_MODE = 'Enhanced'; 34323 34324 function isGpcAsserted() { 34325 return navigator.globalPrivacyControl === true; 34326 } 34327 34328 function readCookiePreferences() { 34329 const match = document.cookie.match(new RegExp('(?:^|; )' + COOKIE_NAME + '=([^;]*)')); 34330 if (!match) { 34331 return null; 34332 } 34333 try { 34334 return JSON.parse(decodeURIComponent(match[1])); 34335 } catch (e) { 34336 return null; 34337 } 34338 } 34339 34340 function hasEnhancedConsent(allowed) { 34341 return Array.isArray(allowed) && allowed.indexOf(ENHANCED_MODE) !== -1; 34342 } 34343 34344 function isGTagAvailable() { 34345 return typeof gtag === 'function'; 34346 } 34347 34348 function isFbqAvailable() { 34349 return typeof fbq === 'function'; 34350 } 34351 34352 function isAgeAdEligible() { 34353 const ctx = window.smpClientPageContext; 34354 if (!ctx || ctx.ageAdEligible === undefined || ctx.ageAdEligible === null) { 34355 return true; 34356 } 34357 return ctx.ageAdEligible === true; 34358 } 34359 34360 function isAdGranted(allowedOverride) { 34361 const allowed = allowedOverride !== undefined ? allowedOverride : readCookiePreferences(); 34362 return hasEnhancedConsent(allowed) && !isGpcAsserted() && isAgeAdEligible(); 34363 } 34364 34365 /// allowedOverride: when just selected by client 34366 function applyFbqConsent(allowedOverride) { 34367 if (!isFbqAvailable()) { 34368 return; 34369 } 34370 34371 fbq('consent', isAdGranted(allowedOverride) ? 'grant' : 'revoke'); 34372 } 34373 34374 function initFbqPageView(allowedOverride) { 34375 if (window.__fbqInitialized || !isFbqAvailable()) { 34376 return; 34377 } 34378 34379 applyFbqConsent(allowedOverride); 34380 fbq('init', '1044302291642337'); 34381 fbq('track', 'PageView', window.fbqPageViewParams || {}); 34382 window.__fbqInitialized = true; 34383 } 34384 34385 /// allowedOverride: when just selected by client 34386 function applyFromCookie(allowedOverride) { 34387 const adGranted = isAdGranted(allowedOverride); 34388 const adGrantedProp = adGranted ? 'granted' : 'denied'; 34389 34390 if (isGTagAvailable()) { 34391 gtag('consent', 'update', { 34392 ad_storage: adGrantedProp, 34393 ad_user_data: adGrantedProp, 34394 ad_personalization: adGrantedProp 34395 }); 34396 34397 gtag('set', 'user_properties', { ad_eligible: adGranted ? 'true' : 'false' }); 34398 } 34399 34400 if (window.__fbqInitialized) { 34401 applyFbqConsent(allowedOverride); 34402 } else { 34403 initFbqPageView(allowedOverride); 34404 } 34405 } 34406 34407 return { 34408 COOKIE_NAME: COOKIE_NAME, 34409 ENHANCED_MODE: ENHANCED_MODE, 34410 isAdGranted: isAdGranted, 34411 applyFbqConsent: applyFbqConsent, 34412 applyFromCookie: applyFromCookie 34413 }; 34414})(); 34415 34416if (!window.__marketingConsentDomReadyRegistered && typeof $ !== 'undefined') { 34417 window.__marketingConsentDomReadyRegistered = true; 34418 $(function () { 34419 window.MarketingConsent.applyFromCookie(); 34420 }); 34421} 34422 34423 34424; 34425////pf: javascript/ga4-analytics.js 34426var GA4 = (function () { 34427 function isAvailable() { 34428 return typeof gtag === 'function'; 34429 } 34430 34431 const isDebug = location.hostname === 'localhost' || location.hostname.indexOf('staging') !== -1; 34432 34433 function sendEvent(eventName, params) { 34434 params = params || {}; 34435 if (!params.traffic_source) { 34436 const trafficSource = getTrafficSource(); 34437 if (trafficSource) params.traffic_source = trafficSource; 34438 } 34439 if (isDebug) { 34440 console.log('%cGA4 Event: ' + eventName, 'color: #4285f4; font-weight: bold;', params); 34441 } 34442 if (!isAvailable()) return; 34443 gtag('event', eventName, params); 34444 } 34445 34446 function buildItems(items) { 34447 if (!items || !items.length) return []; 34448 const stringKeys = ['item_id', 'item_name', 'item_brand', 'item_category', 'item_category2', 34449 'item_category3', 'item_variant', 'item_type', 'size', 34450 'program_name', 'program_type', 'program_sport']; 34451 const boolKeys = ['team_specific', 'required', 'is_marketplace', 'is_add_on']; 34452 return items.map(function (item, index) { 34453 const mapped = {};
34454 stringKeys.forEach(function (k) { if (item[k]) mapped[k] = item[k]; }); 34455 boolKeys.forEach(function (k) { if (item[k] !== undefined) mapped[k] = item[k]; }); 34456 const programId = toProgramId(item.program_id); 34457 if (programId) mapped.program_id = programId; 34458 const price = (item.price !== undefined && item.price !== null) ? parseFloat(item.price) : 0; 34459 const quantity = (item.quantity !== undefined && item.quantity !== null) ? parseInt(item.quantity) : 0; 34460 mapped.price = price; 34461 mapped.quantity = quantity; 34462 mapped.currency = item.currency || 'USD'; 34463 mapped.item_revenue = +(price * quantity).toFixed(2); 34464 mapped.index = (item.index !== undefined && item.index !== null) ? item.index : index; 34465 return mapped; 34466 }); 34467 } 34468 34469 function toProgramId(value) { 34470 const parsed = parseInt(value, 10); 34471 return isNaN(parsed) || parsed <= 0 ? null : parsed; 34472 } 34473 34474 const programContextKey = 'ga4_program_context'; 34475 const programContextFields = ['program_id', 'program_name', 'program_type', 'program_sport']; 34476 const marketplaceUsedKey = 'ga4_marketplace_used'; 34477 34478 function warnStorage(e) { 34479 if (isDebug) console.warn('GA4 storage unavailable', e); 34480 } 34481 34482 function setProgramContext(params) { 34483 const ctx = {}; 34484 programContextFields.forEach(function (k) { if (params[k]) ctx[k] = params[k]; }); 34485 try { sessionStorage.setItem(programContextKey, JSON.stringify(ctx)); } catch (e) { warnStorage(e); } 34486 } 34487 34488 function getProgramContext() { 34489 try { return JSON.parse(sessionStorage.getItem(programContextKey) || '{}'); } catch (e) { warnStorage(e); return {}; } 34490 } 34491 34492 function clearProgramContext() { 34493 try { sessionStorage.removeItem(programContextKey); } catch (e) { warnStorage(e); } 34494 } 34495 34496 function setMarketplaceUsed(used) { 34497 try { sessionStorage.setItem(marketplaceUsedKey, used ? 'true' : 'false'); } catch (e) { warnStorage(e); } 34498 } 34499 34500 function getMarketplaceUsed() { 34501 try { return sessionStorage.getItem(marketplaceUsedKey) === 'true'; } catch (e) { warnStorage(e); return false; } 34502 } 34503 34504 function clearMarketplaceUsed() { 34505 try { sessionStorage.removeItem(marketplaceUsedKey); } catch (e) { warnStorage(e); } 34506 } 34507 34508 const trafficSourceKey = 'ga4_traffic_source'; 34509 34510 function setTrafficSource(source) { 34511 try { sessionStorage.setItem(trafficSourceKey, source); } catch (e) { warnStorage(e); } 34512 } 34513 34514 function getTrafficSource() { 34515 try { return sessionStorage.getItem(trafficSourceKey) || ''; } catch (e) { warnStorage(e); return ''; } 34516 } 34517 34518 function normalizeTrafficSource(value) { 34519 const normalized = (value || '').trim().toLowerCase().replace(/\s+/g, '_'); 34520 return normalized === 'buynow' ? 'buy_now' : normalized; 34521 } 34522 34523 function captureTrafficSource() { 34524 try { 34525 const utmSource = new URLSearchParams(window.location.search).get('utm_source'); 34526 if (!utmSource) return; 34527 const normalized = normalizeTrafficSource(utmSource); 34528 if (normalized) setTrafficSource(normalized); 34529 } catch (e) { if (isDebug) console.warn('GA4 traffic source capture failed', e); } 34530 } 34531 34532 captureTrafficSource(); 34533 34534 function mergeFunnelContext(params) { 34535 const ctx = getProgramContext(); 34536 programContextFields.forEach(function (k) { 34537 if (!params[k]) params[k] = ctx[k] || ''; 34538 }); 34539 if (!params.program_id && params.items && params.items.length) { 34540 const firstProgramId = params.items[0].program_id; 34541 const sameProgram = firstProgramId && params.items.every(function (i) { return i.program_id === firstProgramId; }); 34542 if (sameProgram) { 34543 programContextFields.forEach(function (k) { 34544 const v = params.items[0][k]; 34545 if (v && params.items.every(function (i) { return i[k] === v; })) { 34546 params[k] = v; 34547 } 34548 }); 34549 } 34550 } 34551 if (params.marketplace_used !== true && params.marketplace_used !== false) { 34552 params.marketplace_used = getMarketplaceUsed(); 34553 } 34554 const programId = toProgramId(params.program_id); 34555 if (programId) params.program_id = programId; else delete params.program_id; 34556 return params; 34557 } 34558 34559 function getUserType(serverValue) {
34560 const key = 'ga4_user_type'; 34561 if (serverValue) { 34562 try { sessionStorage.setItem(key, serverValue); } catch (e) {} 34563 return serverValue; 34564 } 34565 try { return sessionStorage.getItem(key) || ''; } catch (e) { return ''; } 34566 } 34567 34568 function buildRegistrationParams(params) { 34569 const stringKeys = ['program_name', 'program_type', 'registration_type', 34570 'program_sport', 'seasons', 'team_id', 'team_name', 'program_age_group', 34571 'program_gender', 'profile_gender_1', 'profile_gender_2', 'profile_id']; 34572 const numericKeys = ['profile_age_1', 'profile_age_2']; 34573 const event_params = {}; 34574 stringKeys.forEach(function (k) { event_params[k] = params[k] || ''; }); 34575 const programId = toProgramId(params.program_id); 34576 if (programId) event_params.program_id = programId; 34577 numericKeys.forEach(function (k) { 34578 event_params[k] = (params[k] !== undefined && params[k] !== null && params[k] !== '') 34579 ? parseInt(params[k]) : ''; 34580 }); 34581 event_params.user_type = getUserType(params.user_type) || ''; 34582 return event_params; 34583 } 34584 34585 return { 34586 isDebug: isDebug, 34587 34588 setProgramContext: setProgramContext, 34589 getProgramContext: getProgramContext, 34590 clearProgramContext: clearProgramContext, 34591 setMarketplaceUsed: setMarketplaceUsed, 34592 getMarketplaceUsed: getMarketplaceUsed, 34593 clearMarketplaceUsed: clearMarketplaceUsed, 34594 getTrafficSource: getTrafficSource, 34595 34596 viewItemList: function (params) { 34597 const event_params = { 34598 item_list_id: params.item_list_id || '', 34599 item_list_name: params.item_list_name || '', 34600 profile_id: params.profile_id || '', 34601 items: buildItems(params.items) 34602 }; 34603 if (params.product_filter) event_params.product_filter = params.product_filter; 34604 sendEvent('view_item_list', mergeFunnelContext(event_params)); 34605 }, 34606 34607 viewItem: function (params) { 34608 sendEvent('view_item', mergeFunnelContext({ 34609 currency: params.currency || 'USD', 34610 value: parseFloat(params.value || 0), 34611 profile_id: params.profile_id || '', 34612 items: buildItems(params.items) 34613 })); 34614 }, 34615 34616 addToCart: function (params) { 34617 sendEvent('add_to_cart', mergeFunnelContext({ 34618 currency: params.currency || 'USD', 34619 value: parseFloat(params.value || 0), 34620 cart_type: params.cart_type || '', 34621 profile_id: params.profile_id || '', 34622 items: buildItems(params.items) 34623 })); 34624 }, 34625 34626 removeFromCart: function (params) { 34627 sendEvent('remove_from_cart', mergeFunnelContext({ 34628 currency: params.currency || 'USD', 34629 value: parseFloat(params.value || 0), 34630 cart_type: params.cart_type || '', 34631 profile_id: params.profile_id || '', 34632 items: buildItems(params.items) 34633 })); 34634 }, 34635 34636 viewCart: function (params) { 34637 sendEvent('view_cart', mergeFunnelContext({ 34638 currency: params.currency || 'USD', 34639 value: parseFloat(params.value || 0), 34640 profile_id: params.profile_id || '', 34641 items: buildItems(params.items) 34642 })); 34643 }, 34644 34645 beginCheckout: function (params) { 34646 sendEvent('begin_checkout', mergeFunnelContext({ 34647 currency: params.currency || 'USD', 34648 value: parseFloat(params.value || 0), 34649 profile_id: params.profile_id || '', 34650 items: buildItems(params.items) 34651 })); 34652 }, 34653 34654 addPaymentInfo: function (params) { 34655 sendEvent('add_payment_info', mergeFunnelContext({ 34656 currency: params.currency || 'USD',
34657 value: parseFloat(params.value || 0), 34658 payment_type: params.payment_type || '', 34659 profile_id: params.profile_id || '', 34660 items: buildItems(params.items) 34661 })); 34662 }, 34663 34664 purchase: function (params) { 34665 sendEvent('purchase', mergeFunnelContext({ 34666 transaction_id: params.transaction_id || '', 34667 currency: params.currency || 'USD', 34668 value: parseFloat(params.value || 0), 34669 profile_id: params.profile_id || '', 34670 items: buildItems(params.items) 34671 })); 34672 clearProgramContext(); 34673 clearMarketplaceUsed(); 34674 }, 34675 34676 registrationStart: function (params) { 34677 setProgramContext(params); 34678 setMarketplaceUsed(false); 34679 const event_params = mergeFunnelContext(buildRegistrationParams(params)); 34680 event_params.marketplace_eligible = params.marketplace_eligible || ''; 34681 sendEvent('registration_start', event_params); 34682 }, 34683 34684 registrationStep: function (params) { 34685 const event_params = mergeFunnelContext(buildRegistrationParams(params)); 34686 event_params.registration_step_name = params.registration_step_name || ''; 34687 sendEvent('registration_step', event_params); 34688 }, 34689 34690 registrationComplete: function (params) { 34691 const event_params = mergeFunnelContext(buildRegistrationParams(params)); 34692 event_params.value = parseFloat(params.value || 0); 34693 event_params.currency = params.currency || 'USD'; 34694 event_params.marketplace_used = params.marketplace_used === true; 34695 event_params.items = buildItems(params.items); 34696 sendEvent('registration_complete', event_params); 34697 } 34698 }; 34699})(); 34700 34701 34702;
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.