PageSourceSearch

https://www.hoopseen.com/masters/themes/clean/build.js?t=639258670420000000

js hoopseen.com collected 2026-09-24 21:06:05 UTC 1,936,854 bytes, 34,702 lines download raw bytes

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(/&nbsp;|&#160;/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("&lt;").split(">").join("&gt;").split('"').join("&#34;").split("'").join("&#39;") } }); 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, '&amp;')
1800            .replace(/</g, '&lt;')
1801            .replace(/>/g, '&gt;')
1802            .replace(/"/g, '&quot;')
1803            .replace(/'/g, '&#39;');
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    "&": "&amp;",
6791    "<": "&lt;",
6792    ">": "&gt;",
6793    '"': '&quot;',
6794    "'": '&#39;',
6795    "/": '&#x2F;'
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, '&amp;')
14553            .replace(/"/g, '&quot;')
14554            .replace(/'/g, '&#39;')
14555            .replace(/</g, '&lt;')
14556            .replace(/>/g, '&gt;');
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||"&#160;",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||"&#160;"));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&#8230;</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?"&#xa0;":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)?"&#xa0;":""));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)?"&#xa0;":"")+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 || '&nbsp;';
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 = '&nbsp;';
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?"&#128104;".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.